P2PServer.cpp
上传用户:hgd7758
上传日期:2007-12-10
资源大小:29k
文件大小:5k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* P2P 程序服务端
  2.  * 
  3.  * 文件名:P2PServer.c
  4.  *
  5.  * 日期:2004-5-21
  6.  *
  7.  * 作者:shootingstars(zhouhuis22@sina.com)
  8.  *
  9.  */
  10. #pragma comment(lib, "ws2_32.lib")
  11. #include "windows.h"
  12. #include "..proto.h"
  13. #include "..Exception.h"
  14. UserList ClientList;
  15. void InitWinSock()
  16. {
  17. WSADATA wsaData;
  18. if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
  19. {
  20. printf("Windows sockets 2.2 startup");
  21. throw Exception("");
  22. }
  23. else{
  24. printf("Using %s (Status: %s)n",
  25. wsaData.szDescription, wsaData.szSystemStatus);
  26. printf("with API versions %d.%d to %d.%dnn",
  27. LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion),
  28. LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
  29. }
  30. }
  31. SOCKET mksock(int type)
  32. {
  33. SOCKET sock = socket(AF_INET, type, 0);
  34. if (sock < 0)
  35. {
  36.         printf("create socket error");
  37. throw Exception("");
  38. }
  39. return sock;
  40. }
  41. stUserListNode GetUser(char *username)
  42. {
  43. for(UserList::iterator UserIterator=ClientList.begin();
  44. UserIterator!=ClientList.end();
  45. ++UserIterator)
  46. {
  47. if( strcmp( ((*UserIterator)->userName), username) == 0 )
  48. return *(*UserIterator);
  49. }
  50. throw Exception("not find this user");
  51. }
  52. int main(int argc, char* argv[])
  53. {
  54. try{
  55. InitWinSock();
  56. SOCKET PrimaryUDP;
  57. PrimaryUDP = mksock(SOCK_DGRAM);
  58. sockaddr_in local;
  59. local.sin_family=AF_INET;
  60. local.sin_port= htons(SERVER_PORT); 
  61. local.sin_addr.s_addr = htonl(INADDR_ANY);
  62. int nResult=bind(PrimaryUDP,(sockaddr*)&local,sizeof(sockaddr));
  63. if(nResult==SOCKET_ERROR)
  64. throw Exception("bind error");
  65. sockaddr_in sender;
  66. stMessage recvbuf;
  67. memset(&recvbuf,0,sizeof(stMessage));
  68. // 开始主循环.
  69. // 主循环负责下面几件事情:
  70. // 一:读取客户端登陆和登出消息,记录客户列表
  71. // 二:转发客户p2p请求
  72. for(;;)
  73. {
  74. int dwSender = sizeof(sender);
  75. int ret = recvfrom(PrimaryUDP, (char *)&recvbuf, sizeof(stMessage), 0, (sockaddr *)&sender, &dwSender);
  76. if(ret <= 0)
  77. {
  78. printf("recv error");
  79. continue;
  80. }
  81. else
  82. {
  83. int messageType = recvbuf.iMessageType;
  84. switch(messageType){
  85. case LOGIN:
  86. {
  87. //  将这个用户的信息记录到用户列表中
  88. printf("has a user login : %sn", recvbuf.message.loginmember.userName);
  89. stUserListNode *currentuser = new stUserListNode();
  90. strcpy(currentuser->userName, recvbuf.message.loginmember.userName);
  91. currentuser->ip = ntohl(sender.sin_addr.S_un.S_addr);
  92. currentuser->port = ntohs(sender.sin_port);
  93. ClientList.push_back(currentuser);
  94. // 发送已经登陆的客户信息
  95. int nodecount = (int)ClientList.size();
  96. sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
  97. for(UserList::iterator UserIterator=ClientList.begin();
  98. UserIterator!=ClientList.end();
  99. ++UserIterator)
  100. {
  101. sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender)); 
  102. }
  103. break;
  104. }
  105. case LOGOUT:
  106. {
  107. // 将此客户信息删除
  108. printf("has a user logout : %sn", recvbuf.message.logoutmember.userName);
  109. UserList::iterator removeiterator = NULL;
  110. for(UserList::iterator UserIterator=ClientList.begin();
  111. UserIterator!=ClientList.end();
  112. ++UserIterator)
  113. {
  114. if( strcmp( ((*UserIterator)->userName), recvbuf.message.logoutmember.userName) == 0 )
  115. {
  116. removeiterator = UserIterator;
  117. break;
  118. }
  119. }
  120. if(removeiterator != NULL)
  121. ClientList.remove(*removeiterator);
  122. break;
  123. }
  124. case P2PTRANS:
  125. {
  126. // 某个客户希望服务端向另外一个客户发送一个打洞消息
  127. printf("%s wants to p2p %sn",inet_ntoa(sender.sin_addr),recvbuf.message.translatemessage.userName);
  128. stUserListNode node = GetUser(recvbuf.message.translatemessage.userName);
  129. sockaddr_in remote;
  130. remote.sin_family=AF_INET;
  131. remote.sin_port= htons(node.port); 
  132. remote.sin_addr.s_addr = htonl(node.ip);
  133. in_addr tmp;
  134. tmp.S_un.S_addr = htonl(node.ip);
  135. printf("the address is %s,and port is %dn",inet_ntoa(tmp), node.port);
  136. stP2PMessage transMessage;
  137. transMessage.iMessageType = P2PSOMEONEWANTTOCALLYOU;
  138. transMessage.iStringLen = ntohl(sender.sin_addr.S_un.S_addr);
  139. transMessage.Port = ntohs(sender.sin_port);
  140.                         
  141. sendto(PrimaryUDP,(const char*)&transMessage, sizeof(transMessage), 0, (const sockaddr *)&remote, sizeof(remote));
  142. break;
  143. }
  144. case GETALLUSER:
  145. {
  146. int command = GETALLUSER;
  147. sendto(PrimaryUDP, (const char*)&command, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
  148. int nodecount = (int)ClientList.size();
  149. sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
  150. for(UserList::iterator UserIterator=ClientList.begin();
  151. UserIterator!=ClientList.end();
  152. ++UserIterator)
  153. {
  154. sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender)); 
  155. }
  156. break;
  157. }
  158. }
  159. }
  160. }
  161. }
  162. catch(Exception &e)
  163. {
  164. printf(e.GetMessage());
  165. return 1;
  166. }
  167. return 0;
  168. }