ServerSockHandler.cpp
上传用户:tt_chan
上传日期:2009-12-03
资源大小:4523k
文件大小:8k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. extern HWND g_hMainWnd;
  3. #ifndef _SOCKET_ASYNC_IO
  4. HANDLE g_hIOCP = NULL;
  5. //unsigned long g_lAcceptThread = 0;
  6. HANDLE g_hAcceptThread = INVALID_HANDLE_VALUE;
  7. //UINT WINAPI AcceptThread(LPVOID lpParameter);
  8. DWORD WINAPI AcceptThread(LPVOID lpParameter);
  9. DWORD WINAPI ServerWorkerThread(LPVOID lpParameter);
  10. INT CreateIOCPWorkerThread(int nThread);
  11. BOOL InitServerThreadForMsg();
  12. #endif
  13. typedef unsigned (__stdcall *ThreadStartRoutine) (
  14.     LPVOID lpThreadParameter
  15. );
  16. BOOL InitThread(LPTHREAD_START_ROUTINE lpRoutine)
  17. {
  18. DWORD dwThreadIDForMsg = 0;
  19. HANDLE hThreadForMsg = 
  20. (HANDLE) _beginthreadex( NULL, 0, (ThreadStartRoutine) lpRoutine, NULL, 0, (UINT *) &dwThreadIDForMsg );
  21. //HANDLE hThreadForMsg = CreateThread(NULL, 0, lpRoutine, NULL, 0, &dwThreadIDForMsg);
  22. if (hThreadForMsg)
  23. {
  24. CloseHandle(hThreadForMsg);
  25. return TRUE;
  26. }
  27. return FALSE;
  28. }
  29. // **************************************************************************************
  30. //
  31. //
  32. //
  33. // **************************************************************************************
  34. BOOL InitServerSocket(SOCKET &s, SOCKADDR_IN* addr, UINT nMsgID, int nPort, long lEvent)
  35. {
  36. if (s == INVALID_SOCKET)
  37. {
  38. #ifdef _SOCKET_ASYNC_IO
  39. s = socket(AF_INET, SOCK_STREAM, 0);
  40. #else
  41. s = WSASocketA(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
  42. #endif
  43. addr->sin_family = AF_INET;
  44. addr->sin_port = htons(nPort);
  45. addr->sin_addr.s_addr = htonl(INADDR_ANY);
  46. if ((bind(s, (const struct sockaddr FAR*)addr, sizeof(SOCKADDR_IN))) == SOCKET_ERROR)
  47. return FALSE;
  48. if ((listen(s, 5)) == SOCKET_ERROR)
  49. return FALSE;
  50. #ifdef _SOCKET_ASYNC_IO
  51. if ((WSAAsyncSelect(s, g_hMainWnd, nMsgID, lEvent)) == SOCKET_ERROR)
  52. return FALSE;
  53. #else
  54. #ifdef _SOCKET_OVERLAPPED_IO
  55. if ((WSAAsyncSelect(s, g_hMainWnd, nMsgID, lEvent)) == SOCKET_ERROR)
  56. return FALSE;
  57. #else
  58. // CreateIOCPWorkerThread((int)lEvent);   
  59. CreateIOCPWorkerThread((int)1);
  60. // InitServerThreadForMsg();
  61. if (!InitThread(AcceptThread))
  62. return FALSE;
  63. #endif
  64. #endif
  65. }
  66. else 
  67. return FALSE;
  68. return TRUE;
  69. }
  70. // **************************************************************************************
  71. //
  72. //
  73. //
  74. // **************************************************************************************
  75. BOOL ClearSocket(SOCKET &s)
  76. {
  77. if (s != INVALID_SOCKET)
  78. {
  79. LINGER lingerStruct;
  80. lingerStruct.l_onoff = 1;
  81. lingerStruct.l_linger = 0;
  82. setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct));
  83. closesocket(s);
  84. s = INVALID_SOCKET;
  85. return TRUE;
  86. }
  87. return FALSE;
  88. }
  89. // **************************************************************************************
  90. //
  91. //
  92. //
  93. // **************************************************************************************
  94. BOOL ConnectToServer(SOCKET &s, SOCKADDR_IN* addr, UINT nMsgID, LPCTSTR lpServerIP, DWORD dwIP, int nPort, long lEvent)
  95. {
  96. if (s != INVALID_SOCKET)
  97. {
  98. closesocket(s);
  99. s = INVALID_SOCKET;
  100. }
  101. s = socket(AF_INET, SOCK_STREAM, 0);
  102. addr->sin_family = AF_INET;
  103. addr->sin_port = htons(nPort);
  104. if (lpServerIP)
  105. {
  106. char szIP[24];
  107. WideCharToMultiByte(CP_ACP, 0, lpServerIP, -1, szIP, sizeof(szIP), NULL, NULL);
  108. addr->sin_addr.s_addr = inet_addr(szIP);
  109. }
  110. else
  111. {
  112. DWORD dwReverseIP = 0;
  113. dwReverseIP = (LOBYTE(LOWORD(dwIP)) << 24) | (HIBYTE(LOWORD(dwIP)) << 16) | (LOBYTE(HIWORD(dwIP)) << 8) | (HIBYTE(HIWORD(dwIP)));
  114. addr->sin_addr.s_addr = dwReverseIP;
  115. }
  116. if (WSAAsyncSelect(s, g_hMainWnd, nMsgID, lEvent) == SOCKET_ERROR)
  117. return FALSE;
  118. if (connect(s, (const struct sockaddr FAR*)addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
  119. {
  120. if (WSAGetLastError() == WSAEWOULDBLOCK)
  121. return TRUE;
  122. }
  123. return FALSE;
  124. }
  125. // **************************************************************************************
  126. //
  127. //
  128. //
  129. // **************************************************************************************
  130. BOOL CheckSocketError(LPARAM lParam)
  131. {
  132. switch (WSAGETSELECTERROR(lParam))
  133. {
  134. case WSANOTINITIALISED:
  135. InsertLogMsg(_T("A successful WSAStartup must occur before using this function."));
  136. return FALSE;
  137. case WSAENETDOWN:
  138. InsertLogMsg(_T("The network subsystem has failed."));
  139. return FALSE;
  140. case WSAEADDRINUSE:
  141. InsertLogMsg(_T("The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs when executing bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function."));
  142. return FALSE;
  143. case WSAEINTR:
  144. InsertLogMsg(_T("The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall."));
  145. return FALSE;
  146. case WSAEINPROGRESS:
  147. InsertLogMsg(_T("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function."));
  148. return FALSE;
  149. case WSAEALREADY:
  150. InsertLogMsg(_T("A nonblocking connect call is in progress on the specified socket. Note In order to preserve backward compatibility, this error is reported as WSAEINVAL to Windows Sockets 1.1 applications that link to either WINSOCK.DLL or WSOCK32.DLL."));
  151. return FALSE;
  152. case WSAEADDRNOTAVAIL:
  153. InsertLogMsg(_T("The remote address is not a valid address (such as ADDR_ANY)."));
  154. return FALSE;
  155. case WSAEAFNOSUPPORT:
  156. InsertLogMsg(_T("Addresses in the specified family cannot be used with this socket."));
  157. return FALSE;
  158. case WSAECONNREFUSED: // Can't Connect Server...
  159. case WSAETIMEDOUT: // Time Out
  160. InsertLogMsg(IDS_CANT_CONNECT);
  161. return FALSE;
  162. case WSAEFAULT:
  163. InsertLogMsg(_T("The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, or the name parameter contains incorrect address format for the associated address family."));
  164. return FALSE;
  165. case WSAEINVAL:
  166. InsertLogMsg(_T("The parameter s is a listening socket, or the destination address specified is not consistent with that of the constrained group the socket belongs to."));
  167. return FALSE;
  168. case WSAEISCONN:
  169. InsertLogMsg(_T("The socket is already connected (connection-oriented sockets only)."));
  170. return FALSE;
  171. case WSAENETUNREACH:
  172. InsertLogMsg(_T("The network cannot be reached from this host at this time."));
  173. return FALSE;
  174. case WSAENOBUFS:
  175. InsertLogMsg(_T("No buffer space is available. The socket cannot be connected."));
  176. return FALSE;
  177. case WSAENOTSOCK:
  178. InsertLogMsg(_T("The descriptor is not a socket."));
  179. return FALSE;
  180. case WSAEWOULDBLOCK:
  181. InsertLogMsg(_T("The socket is marked as nonblocking and the connection cannot be completed immediately."));
  182. return FALSE;
  183. case WSAEACCES:
  184. InsertLogMsg(_T("Attempt to connect datagram socket to broadcast address failed because setsockopt option SO_BROADCAST is not enabled."));
  185. return FALSE;
  186. }
  187. return TRUE;
  188. }
  189. // **************************************************************************************
  190. //
  191. //
  192. //
  193. // **************************************************************************************
  194. #ifndef _SOCKET_ASYNC_IO
  195. BOOL CheckAvailableIOCP()
  196. {
  197. // OSVERSIONINFO VersionInfo;
  198. // GetVersionEx(&VersionInfo);
  199. // if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && VersionInfo.dwMajorVersion >= 5)
  200. return TRUE;
  201. // return FALSE;
  202. }
  203. // **************************************************************************************
  204. //
  205. //
  206. //
  207. // **************************************************************************************
  208. INT CreateIOCPWorkerThread(int nThread)
  209. {
  210. DWORD dwThreadID;
  211. if (g_hIOCP != INVALID_HANDLE_VALUE)
  212. {
  213. SYSTEM_INFO SystemInfo;
  214. if ((g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
  215. return -1;
  216. GetSystemInfo(&SystemInfo);
  217. for (UINT i = 0; i < SystemInfo.dwNumberOfProcessors * nThread; i++)
  218. {
  219. HANDLE ThreadHandle;
  220. // if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, g_hIOCP, 0, &dwThreadID)) == NULL)
  221. // return -1;
  222. if ((ThreadHandle = (HANDLE) _beginthreadex(NULL, 0, (ThreadStartRoutine) ServerWorkerThread, g_hIOCP, 0, (UINT *) &dwThreadID)) == NULL )
  223. return -1;
  224. CloseHandle(ThreadHandle);
  225. }
  226. return SystemInfo.dwNumberOfProcessors * nThread;
  227. }
  228. return -1;
  229. }
  230. #endif