ServerSockMsg.cpp
上传用户:szopptop
上传日期:2013-04-23
资源大小:1047k
文件大小:5k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. void SendExToServer(char *pszPacket);
  3. extern SOCKET g_ssock;
  4. extern SOCKET g_csock;
  5. extern HWND g_hStatusBar;
  6. #ifndef _SOCKET_ASYNC_IO
  7. extern HANDLE g_hIOCP;
  8. CWHList<CSessionInfo*> g_xSessionList;
  9. #endif
  10. extern BOOL g_fTerminated;
  11. void UpdateStatusBar(BOOL fGrow)
  12. {
  13. static LONG nNumOfCurrSession = 0;
  14. TCHAR szText[20];
  15. (fGrow ? InterlockedIncrement(&nNumOfCurrSession) : InterlockedDecrement(&nNumOfCurrSession));
  16. wsprintf(szText, _TEXT("%d Sessions"), nNumOfCurrSession);
  17. SendMessage(g_hStatusBar, SB_SETTEXT, MAKEWORD(3, 0), (LPARAM)szText);
  18. }
  19. //UINT WINAPI AcceptThread(LPVOID lpParameter)
  20. DWORD WINAPI AcceptThread(LPVOID lpParameter)
  21. {
  22. int nLen = sizeof(SOCKADDR_IN);
  23. char szMsg[64];
  24. SOCKET Accept;
  25. SOCKADDR_IN Address;
  26. while (TRUE)
  27. {
  28. Accept = accept(g_ssock, (struct sockaddr FAR *)&Address, &nLen);
  29. if (g_fTerminated)
  30. return 0;
  31. CSessionInfo* pNewUserInfo = (CSessionInfo*)GlobalAlloc(GPTR, sizeof(CSessionInfo));
  32. if (pNewUserInfo)
  33. {
  34. pNewUserInfo->sock = Accept;
  35. CreateIoCompletionPort((HANDLE)pNewUserInfo->sock, g_hIOCP, (DWORD)pNewUserInfo, 0);
  36. if (g_xSessionList.AddNewNode(pNewUserInfo))
  37. {
  38. int zero = 0;
  39. setsockopt(pNewUserInfo->sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero) );
  40. // ORZ:
  41. pNewUserInfo->Recv();
  42. UpdateStatusBar(TRUE);
  43. //WSAAddressToString(&AcceptAddr, (DWORD)nAcceptAddrLen, NULL, szAcceptDotAddr, (LPDWORD)&nAcceptDotAddrLen);
  44. // Make packet and send to login server.
  45. //wsprintf(szMsg, _TEXT("%%O%d/%d.%d.%d.%d$"), Accept, Address.sin_addr.s_net, Address.sin_addr.s_host,
  46. // Address.sin_addr.s_lh, Address.sin_addr.s_impno);
  47. szMsg[0] = '%';
  48. szMsg[1] = 'O';
  49. char *pszPos = ValToAnsiStr((int)Accept, &szMsg[2]);
  50. *pszPos++ = '/';
  51. pszPos = ValToAnsiStr((int)Address.sin_addr.s_net, pszPos);
  52. *pszPos++ = '.';
  53. pszPos = ValToAnsiStr((int)Address.sin_addr.s_host, pszPos);
  54. *pszPos++ = '.';
  55. pszPos = ValToAnsiStr((int)Address.sin_addr.s_lh, pszPos);
  56. *pszPos++ = '.';
  57. pszPos = ValToAnsiStr((int)Address.sin_addr.s_impno, pszPos);
  58. *pszPos++ = '$';
  59. *pszPos = '';
  60. SendExToServer(szMsg);
  61. }
  62. }
  63. }
  64. return 0;
  65. }
  66. //void CloseSession(CSessionInfo* pSessionInfo)
  67. void CloseSession(int s)
  68. {
  69. char szMsg[32];
  70. // Send close msg to login server
  71. //wsprintf(szMsg, _TEXT("%%X%d$"), s);
  72. szMsg[0] = '%';
  73. szMsg[1] = 'X';
  74. char *pszPos = ValToAnsiStr(s, &szMsg[2]);
  75. *pszPos++ = '$';
  76. *pszPos = '';
  77. SendExToServer(szMsg); 
  78. closesocket(s);
  79. UpdateStatusBar(FALSE);
  80. }
  81. DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
  82. {
  83. DWORD dwBytesTransferred = 0;
  84. CSessionInfo* pSessionInfo = NULL;
  85. _LPTCOMPLETIONPORT lpPerIoData = NULL;
  86. char szPacket[DATA_BUFSIZE + 20]; // 20 is dummy size 
  87. char szMsg[32];
  88. char *pszPos;
  89. while (TRUE)
  90. {
  91. if (GetQueuedCompletionStatus((HANDLE)CompletionPortID, &dwBytesTransferred, (LPDWORD)&pSessionInfo, 
  92. (LPOVERLAPPED *)&lpPerIoData, INFINITE) == 0)
  93. {
  94. if (g_fTerminated)
  95. return 0;
  96. if (pSessionInfo)
  97. {
  98. szMsg[0] = '%';
  99. szMsg[1] = 'X';
  100. char *pszPos = ValToAnsiStr((int)pSessionInfo->sock, &szMsg[2]);
  101. *pszPos++ = '$';
  102. *pszPos = '';
  103. SendExToServer(szMsg); 
  104. g_xSessionList.RemoveNodeByData(pSessionInfo);
  105. closesocket(pSessionInfo->sock);
  106. pSessionInfo->sock = INVALID_SOCKET;
  107. UpdateStatusBar(FALSE);
  108. GlobalFree(pSessionInfo);
  109. }
  110. continue;
  111. }
  112. if (g_fTerminated)
  113. return 0;
  114. if (dwBytesTransferred == 0)
  115. {
  116. szMsg[0] = '%';
  117. szMsg[1] = 'X';
  118. char *pszPos = ValToAnsiStr((int)pSessionInfo->sock, &szMsg[2]);
  119. *pszPos++ = '$';
  120. *pszPos = '';
  121. SendExToServer(szMsg); 
  122. g_xSessionList.RemoveNodeByData(pSessionInfo);
  123. closesocket(pSessionInfo->sock);
  124. pSessionInfo->sock = INVALID_SOCKET;
  125. UpdateStatusBar(FALSE);
  126. GlobalFree(pSessionInfo);
  127. continue;
  128. }
  129. // ORZ:
  130. pSessionInfo->bufLen += dwBytesTransferred;
  131. while ( pSessionInfo->HasCompletionPacket() )
  132. {
  133. szPacket[0] = '%';
  134. szPacket[1] = 'A';
  135. pszPos = ValToAnsiStr( (int) pSessionInfo->sock, &szPacket[2] );
  136. *pszPos++ = '/';
  137. pszPos = pSessionInfo->ExtractPacket( pszPos );
  138. *pszPos++ = '$';
  139. *pszPos = '';
  140. SendExToServer( szPacket );
  141. }
  142. // ORZ:
  143. if ( pSessionInfo->Recv() == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING )
  144. {
  145. InsertLogMsg(_TEXT("WSARecv() failed"));
  146. CloseSession(pSessionInfo->sock);
  147. continue;
  148. }
  149. }
  150. return 0;
  151. }