P2PServer.cpp
上传用户:hgd7758
上传日期:2007-12-10
资源大小:29k
文件大小:5k
- /* P2P 程序服务端
- *
- * 文件名:P2PServer.c
- *
- * 日期:2004-5-21
- *
- * 作者:shootingstars(zhouhuis22@sina.com)
- *
- */
- #pragma comment(lib, "ws2_32.lib")
- #include "windows.h"
- #include "..proto.h"
- #include "..Exception.h"
- UserList ClientList;
- void InitWinSock()
- {
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- printf("Windows sockets 2.2 startup");
- throw Exception("");
- }
- else{
- printf("Using %s (Status: %s)n",
- wsaData.szDescription, wsaData.szSystemStatus);
- printf("with API versions %d.%d to %d.%dnn",
- LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion),
- LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
-
- }
- }
- SOCKET mksock(int type)
- {
- SOCKET sock = socket(AF_INET, type, 0);
- if (sock < 0)
- {
- printf("create socket error");
- throw Exception("");
- }
- return sock;
- }
- stUserListNode GetUser(char *username)
- {
- for(UserList::iterator UserIterator=ClientList.begin();
- UserIterator!=ClientList.end();
- ++UserIterator)
- {
- if( strcmp( ((*UserIterator)->userName), username) == 0 )
- return *(*UserIterator);
- }
- throw Exception("not find this user");
- }
- int main(int argc, char* argv[])
- {
- try{
- InitWinSock();
-
- SOCKET PrimaryUDP;
- PrimaryUDP = mksock(SOCK_DGRAM);
- sockaddr_in local;
- local.sin_family=AF_INET;
- local.sin_port= htons(SERVER_PORT);
- local.sin_addr.s_addr = htonl(INADDR_ANY);
- int nResult=bind(PrimaryUDP,(sockaddr*)&local,sizeof(sockaddr));
- if(nResult==SOCKET_ERROR)
- throw Exception("bind error");
- sockaddr_in sender;
- stMessage recvbuf;
- memset(&recvbuf,0,sizeof(stMessage));
- // 开始主循环.
- // 主循环负责下面几件事情:
- // 一:读取客户端登陆和登出消息,记录客户列表
- // 二:转发客户p2p请求
- for(;;)
- {
- int dwSender = sizeof(sender);
- int ret = recvfrom(PrimaryUDP, (char *)&recvbuf, sizeof(stMessage), 0, (sockaddr *)&sender, &dwSender);
- if(ret <= 0)
- {
- printf("recv error");
- continue;
- }
- else
- {
- int messageType = recvbuf.iMessageType;
- switch(messageType){
- case LOGIN:
- {
- // 将这个用户的信息记录到用户列表中
- printf("has a user login : %sn", recvbuf.message.loginmember.userName);
- stUserListNode *currentuser = new stUserListNode();
- strcpy(currentuser->userName, recvbuf.message.loginmember.userName);
- currentuser->ip = ntohl(sender.sin_addr.S_un.S_addr);
- currentuser->port = ntohs(sender.sin_port);
-
- ClientList.push_back(currentuser);
- // 发送已经登陆的客户信息
- int nodecount = (int)ClientList.size();
- sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
- for(UserList::iterator UserIterator=ClientList.begin();
- UserIterator!=ClientList.end();
- ++UserIterator)
- {
- sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender));
- }
- break;
- }
- case LOGOUT:
- {
- // 将此客户信息删除
- printf("has a user logout : %sn", recvbuf.message.logoutmember.userName);
- UserList::iterator removeiterator = NULL;
- for(UserList::iterator UserIterator=ClientList.begin();
- UserIterator!=ClientList.end();
- ++UserIterator)
- {
- if( strcmp( ((*UserIterator)->userName), recvbuf.message.logoutmember.userName) == 0 )
- {
- removeiterator = UserIterator;
- break;
- }
- }
- if(removeiterator != NULL)
- ClientList.remove(*removeiterator);
- break;
- }
- case P2PTRANS:
- {
- // 某个客户希望服务端向另外一个客户发送一个打洞消息
- printf("%s wants to p2p %sn",inet_ntoa(sender.sin_addr),recvbuf.message.translatemessage.userName);
- stUserListNode node = GetUser(recvbuf.message.translatemessage.userName);
- sockaddr_in remote;
- remote.sin_family=AF_INET;
- remote.sin_port= htons(node.port);
- remote.sin_addr.s_addr = htonl(node.ip);
- in_addr tmp;
- tmp.S_un.S_addr = htonl(node.ip);
- printf("the address is %s,and port is %dn",inet_ntoa(tmp), node.port);
- stP2PMessage transMessage;
- transMessage.iMessageType = P2PSOMEONEWANTTOCALLYOU;
- transMessage.iStringLen = ntohl(sender.sin_addr.S_un.S_addr);
- transMessage.Port = ntohs(sender.sin_port);
-
- sendto(PrimaryUDP,(const char*)&transMessage, sizeof(transMessage), 0, (const sockaddr *)&remote, sizeof(remote));
- break;
- }
-
- case GETALLUSER:
- {
- int command = GETALLUSER;
- sendto(PrimaryUDP, (const char*)&command, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
- int nodecount = (int)ClientList.size();
- sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
- for(UserList::iterator UserIterator=ClientList.begin();
- UserIterator!=ClientList.end();
- ++UserIterator)
- {
- sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender));
- }
- break;
- }
- }
- }
- }
- }
- catch(Exception &e)
- {
- printf(e.GetMessage());
- return 1;
- }
- return 0;
- }