network.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:5k
源码类别:

游戏

开发平台:

Visual C++

  1. #include "global.h"
  2. #include "msglist.h"
  3. #include "network.h"
  4. #include <winsock2.h>
  5. //-----------------------------------------------------------------------------
  6. // Connection parameters
  7. //-----------------------------------------------------------------------------
  8. #define NET_SERVER_ADDR "127.0.0.1"
  9. #define NET_SERVER_PORT 5500
  10. #define NET_CLIENT_PORT_MIN 5400
  11. #define NET_CLIENT_PORT_MAX 5420
  12. #define BUFFERSIZE 256
  13. //-----------------------------------------------------------------------------
  14. // Variables
  15. //-----------------------------------------------------------------------------
  16. CMsgList NetList;
  17. SOCKET c_socket; // client socket
  18. unsigned int c_port; // client port
  19. bool SendMsg(int msg, LPVOID param, int size);
  20. DWORD WINAPI MsgReceiver( LPVOID param );
  21. //-----------------------------------------------------------------------------
  22. // Name: InitNetwork()
  23. // Desc: Initialize socket for network and connect to the server
  24. //-----------------------------------------------------------------------------
  25. bool InitNetwork( const char *serv_addr, unsigned int serv_port)
  26. {
  27. WSADATA wsd;
  28. sockaddr_in local,server;
  29. unsigned long ul = 1;
  30. int ret;
  31. // Load network library
  32. if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
  33. return false;
  34. // Create a client socket and bind it
  35. c_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  36.     if (c_socket == SOCKET_ERROR)
  37.      return false;
  38. local.sin_addr.s_addr = htonl(INADDR_ANY);
  39. local.sin_family = AF_INET;
  40. c_port = NET_CLIENT_PORT_MIN;
  41. while(c_port < NET_CLIENT_PORT_MAX)
  42. {
  43. local.sin_port = htons(c_port);
  44. if(bind(c_socket,(struct sockaddr *)&local,
  45. sizeof(local)) == SOCKET_ERROR) {
  46. ret = WSAGetLastError();
  47. if(ret == WSAEADDRINUSE)
  48. c_port++;
  49. else break;
  50. }
  51. else break;
  52. }
  53. if(c_port >= NET_CLIENT_PORT_MAX)
  54. return false;
  55. // Connect to the server
  56. server.sin_addr.s_addr  = inet_addr(serv_addr);
  57. server.sin_family = AF_INET;
  58. server.sin_port = htons(serv_port);
  59. if( connect( c_socket, (const sockaddr *)&server,
  60. sizeof(server) ) == SOCKET_ERROR )
  61. {
  62. ret = WSAGetLastError();
  63. if(ret == WSAENETDOWN || ret == WSAENETUNREACH)
  64. ERRORMSG("Can't reach server.nPlease check your network connection.");
  65. else if(ret == WSAECONNREFUSED)
  66. ERRORMSG("The server does not work!");
  67. else if(ret == WSAEPROCLIM)
  68. ERRORMSG("Too many users.nPlease try later.");
  69. return false;
  70. }
  71. // Set nonblock property
  72. if( ioctlsocket( c_socket, FIONBIO, &ul ) == SOCKET_ERROR )
  73. return false;
  74. // Initialize message lists
  75. NetList.CreatMsgList( 8, true ); // network message list
  76. // Create receive thread
  77. HANDLE hThread = CreateThread(NULL,0,MsgReceiver,NULL,0,NULL);
  78. if(!hThread)
  79. return false;
  80. return true;
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Name: SendMsg()
  84. // Desc: Function for sending messages to the server
  85. //-----------------------------------------------------------------------------
  86. bool SendMsg(int msg, LPVOID param, int size)
  87. {
  88. int ret = size+sizeof(int)*2;
  89. char *buffer = new char[ret];
  90. if(!buffer)
  91. return false;
  92. *(int *)buffer = msg;
  93. *(int *)(buffer+sizeof(int)) = size;
  94. if(param && size>0)
  95. memcpy( buffer+sizeof(int)*2, param, size );
  96. ret = send(c_socket,buffer,ret,0);
  97. delete[] buffer;
  98. if( ret == SOCKET_ERROR)
  99. return false;
  100. else
  101. return true;
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Name: MsgReceiver()
  105. // Desc: Initialize socket for network and connect to the server
  106. //-----------------------------------------------------------------------------
  107. DWORD WINAPI MsgReceiver( LPVOID param )
  108. {
  109. fd_set fdread;
  110. timeval tval;
  111. int ret, msgsize;
  112. char buf_char[BUFFERSIZE]; // receive buffer
  113. char *mark;
  114. CMsgElem elem;
  115. // initiate communication
  116. ret = 0;
  117. SendMsg( NETMSGTK_ASKGROUPINFO, &ret, sizeof(int) );
  118. tval.tv_usec = 0;
  119. tval.tv_sec  = 1;
  120. while(true)
  121. {
  122. FD_ZERO(&fdread);
  123. FD_SET(c_socket,&fdread);
  124. ret = select(0,&fdread,NULL,NULL,&tval);
  125. if ( ret == 0 || ret == SOCKET_ERROR ) {
  126. ret = WSAGetLastError();
  127. continue;
  128. }
  129. if ( !NetList.GetSize() ) // may be not initialized yet
  130. continue;
  131. ret = recv(c_socket,buf_char,BUFFERSIZE,0);
  132. if(ret == SOCKET_ERROR) {
  133. ret = WSAGetLastError();
  134. NetList.Lock();
  135. char *temp = "Connection shutdown!";
  136. elem.CreateMsgElem(MSGNET_RECEIVEERROR, temp, strlen(temp)+1, MSG_NET );
  137. NetList.Push(&elem);
  138. NetList.UnLock();
  139. break;
  140. }
  141. // Peek message details and push into the list
  142. NetList.Lock();
  143. mark = buf_char;
  144. while ( ret > 0 && 
  145. elem.CreateMsgElemFromBuf( mark, msgsize, MSG_NET ) ) {
  146. NetList.Push(&elem);
  147. mark += msgsize;
  148. ret -= msgsize;
  149. }
  150. NetList.UnLock();
  151. }
  152. return 0;
  153. }