fork download
  1. #include "stdafx.h"
  2. #include <winsock2.h>
  3. #pragma comment(lib, "ws2_32")
  4. #include <windows.h>
  5. #include <list>
  6. #include <iterator>
  7. #include<time.h>
  8. /////////////////////////////////////////////////////////////////////////
  9. CRITICAL_SECTION g_cs; //Thread synchronization object.
  10. SOCKET g_hSocket; //server's listen socket
  11. std::list<SOCKET> g_listClient; //List of linked client sockets. Manage sockets with a linked list.
  12.  
  13. //Save the socket of the newly connected client to the list.
  14. BOOL AddUser(SOCKET hSocket)
  15. {
  16. ::EnterCriticalSection(&g_cs);
  17. g_listClient.push_back( hSocket );
  18. ::LeaveCriticalSection(&g_cs);
  19.  
  20. return TRUE;
  21. }
  22.  
  23. /////////////////////////////////////////////////////////////////////////
  24. //Send messages to all connected clients.
  25. void SendChattingMessage(char *pszParam)
  26. {
  27. int nLength = strlen(pszParam);
  28. std::list<SOCKET>::iterator it;
  29.  
  30. ::EnterCriticalSection(&g_cs);
  31. for (it = g_listClient.begin(); it != g_listClient.end(); ++it)
  32. ::send(*it, pszParam, sizeof(char)* (nLength + 1), 0);
  33. ::LeaveCriticalSection(&g_cs);
  34. }
  35.  
  36. /////////////////////////////////////////////////////////////////////////
  37. //Ctrl+C when detect event, terminate program
  38. BOOL CtrlHandler(DWORD dwType)
  39. {
  40. if (dwType == CTRL_C_EVENT)
  41. {
  42. std::list<SOCKET>::iterator it;
  43.  
  44. //Close all connected clients and listening sockets and exit the program.
  45. ::shutdown(g_hSocket, SD_BOTH);
  46.  
  47. ::EnterCriticalSection(&g_cs);
  48. for (it = g_listClient.begin(); it != g_listClient.end(); ++it)
  49. ::closesocket(*it);
  50. //Delete all information registered in the list of links.
  51. g_listClient.clear();
  52. ::LeaveCriticalSection(&g_cs);
  53.  
  54. puts("All client connections have been terminated.");
  55. //Wait for the threads communicating with the client to end.
  56. ::Sleep(100);
  57. ::DeleteCriticalSection(&g_cs);
  58. ::closesocket(g_hSocket);
  59.  
  60. ::WSACleanup();
  61. exit(0);
  62. return TRUE;
  63. }
  64.  
  65. return FALSE;
  66. }
  67. int flag = 0;
  68. time_t start, end;
  69. /////////////////////////////////////////////////////////////////////////
  70. //thread function that provides a chat message service to clients.
  71. //One thread is created for each connected client.
  72. DWORD WINAPI ThreadFunction(LPVOID pParam)
  73. {
  74. char szBuffer[128] = { 0 };
  75. int nReceive = 0;
  76. SOCKET hClient = (SOCKET)pParam;
  77.  
  78. if (flag == 0) {
  79. flag = 1;
  80. start = time(NULL);
  81. }
  82. std::cout << (double)(time(NULL) - start) << std::endl;
  83.  
  84. puts("connected new client");
  85. while ((nReceive = ::recv(hClient,
  86. szBuffer, sizeof(szBuffer), 0)) > 0)
  87. {
  88. puts(szBuffer);
  89. //Send received strings to all connected clients
  90. SendChattingMessage(szBuffer);
  91. memset(szBuffer, 0, sizeof(szBuffer));
  92. }
  93.  
  94. puts("disconnected by client");
  95. ::EnterCriticalSection(&g_cs);
  96. g_listClient.remove(hClient);
  97. ::LeaveCriticalSection(&g_cs);
  98.  
  99. ::closesocket(hClient);
  100. return 0;
  101. }
  102.  
  103. /////////////////////////////////////////////////////////////////////////
  104. int _tmain(int argc, _TCHAR* argv[])
  105. {
  106.  
  107. WSADATA wsa = { 0 };
  108. if (::WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
  109. {
  110. puts("ERROR: Can't initial window socket");
  111. return 0;
  112. }
  113.  
  114.  
  115. ::InitializeCriticalSection(&g_cs);
  116.  
  117. //When the Ctrl+C key is pressed, it detects it and registers the function to be processed.
  118. if ( ::SetConsoleCtrlHandler(
  119. (PHANDLER_ROUTINE)CtrlHandler, TRUE) == FALSE )
  120. puts("ERROR: Unable to enroll Ctrl+C controller");
  121.  
  122. //Create Connection Waiting Socket
  123. g_hSocket = ::socket(AF_INET, SOCK_STREAM, 0);
  124. if (g_hSocket == INVALID_SOCKET)
  125. {
  126. puts("ERROR: Unable to create connection waiting socket.");
  127. return 0;
  128. }
  129.  
  130.  
  131. SOCKADDR_IN svraddr = { 0 };
  132. svraddr.sin_family = AF_INET;
  133. svraddr.sin_port = htons(25000);
  134. svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  135. if (::bind(g_hSocket,
  136. (SOCKADDR*)&svraddr, sizeof(svraddr)) == SOCKET_ERROR)
  137. {
  138. puts("ERROR: Unable to port and Ip into socket");
  139. return 0;
  140. }
  141.  
  142. //
  143. if (::listen(g_hSocket, SOMAXCONN) == SOCKET_ERROR)
  144. {
  145. puts("ERROR: Unable to convert Listen status");
  146. return 0;
  147. }
  148. puts("*** Start Chatting server ***");
  149.  
  150. //Process and respond to client connections
  151. SOCKADDR_IN clientaddr = { 0 };
  152. int nAddrLen = sizeof(clientaddr);
  153. SOCKET hClient = 0;
  154. DWORD dwThreadID = 0;
  155. HANDLE hThread;
  156.  
  157. //Accept client connections and create a new socket (open)
  158.  
  159. while ((hClient = ::accept(g_hSocket,
  160. (SOCKADDR*)&clientaddr, &nAddrLen)) != INVALID_SOCKET)
  161. {
  162. if (AddUser(hClient) == FALSE)
  163. {
  164. puts("ERROR: Unable to process client connection.");
  165. CtrlHandler(CTRL_C_EVENT);
  166. break;
  167. }
  168.  
  169. //Received a string from the client.
  170. hThread = ::CreateThread(NULL,
  171. 0,
  172. ThreadFunction,
  173. (LPVOID)hClient,
  174. 0,
  175. &dwThreadID);
  176.  
  177. ::CloseHandle(hThread);
  178. }
  179.  
  180. puts("*** terminate chatting server ***");
  181. return 0;
  182. }
  183.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:10: fatal error: stdafx.h: No such file or directory
 #include "stdafx.h"
          ^~~~~~~~~~
compilation terminated.
stdout
Standard output is empty