基于visual c++之windows核心编程代码分析(10)实现socket通信

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-26 09:11   50   0
在多台计算机之间实现通信,最常见的方法有两种:Socket通信与UDP通信。
Socket是一种基于TCP/IP协议,建立稳定连接的点对点通信,它的特点是安全性高,数据
不会丢失,但是很占系统资源。
在JAVA中,ServerSocket类和Socket类为我们实现了Socket通信,建立通信的一般步骤是:
1。建立服务器
ServerSocket ss = new ServerSocket(端口号);
Socket socket = ss.accept();
这样,我们就已经建立了服务器,其中accept()方法会阻塞,知道有客户发送一个连接请求,我们可以通过socket.getInputStream()和socket.getOutputStream()来获得输入输出流,如调用socket.getInputStream()获得一个输入流,实际上这个流就是连接对方的一个输出流,流的操作与文件流操作相同,我们可以用操作文件的方法来操作它们。
2。建立客户端
Socket socket = new Socket(主机名,端口号)
客户端只需这一句代码就可以与服务器取得连接,这里的主机名应为服务器的IP地址,端口号是服务器用来监听该程序的端口,同样可以通过socket.getInputStream()和socket.getOutputStream()来获得输入输出流。在以上程序中,已经实现了一个最简单的客户端和服务器的通信。但是,还有一些问题。
首先,这个通信只执行一次,程序就将结束。因为我们只读了一次输入流,如果想要建立客户与服务器之间的稳定的会话,就要用到多线程:
Thread thread = new Thread(new Sender());
thread.start();

InputStream input = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(input));
while(true){
br.readLine();
}
其中,Sender是一个实现了Runnable接口的类,用它来专门负责发送数据,主线程只需要不听地接受数据就行。Sender类中的run()方法应该具有以下代码:
PrintWriter pw = new PrintWriter(socket.getOutputStream());
while(true){
pw.println(数据);
}
即使按上面的方式做了,程序还是有问题,因为它只能在一个时间内为一个客户服务,不能同时为多个客户服务,如多要想同时为多个客户服务,服务器应具有类似以下的代码:
ServerSocker ss = new ServerSocker(端口号);
socket = null;
while(true){
socket = ss.accept();
Thread thread1 = new Thread(new Sender());
thread1.start();
Thread thread2 = new Thread(new Receiver());
thread2.start();
}
在这里,新开启了2个线程分别负责接收和发送。Receiver是一个与Sender非常相似的类,它主要用来接收数据。在客户端,我们同样应开启2个线程:
Socket socket = new Socket(服务器IP,端口号);
Sender sender = new Sender(socket);
Thread thread1 = new Thread(sender);
thread1.start();

Receiver receiver = new Receiver(socket);
Thread thread2 = new Thread(receiver);
thread2.start();

我们来亲自动手实现案例

实现客户端

  1. /* 头文件 */
  2. #include <stdio.h>
  3. #include "winsock2.h"
  4. /* 常量 */
  5. #define RECV_BUFFER_SIZE 8192
  6. /*************************************
  7. * main
  8. * 功能 socket通信客户端
  9. **************************************/
  10. void main(int argc, char* argv[])
  11. {
  12. // 变量定义
  13. SOCKADDR_IN clientService;// 地址
  14. SOCKET ConnectSocket;// socket
  15. WSADATA wsaData;// 库
  16. LPVOID recvbuf;// 接收缓存
  17. int bytesSent;
  18. int bytesRecv = 0;
  19. char sendbuf[32] = "get information";// 默认发送的数据
  20. // 初始化socket库, 保存ws2_32.dll已经加载
  21. int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  22. if (iResult != NO_ERROR)
  23. printf("Error at WSAStartup()\n");
  24. // 创建socket
  25. ConnectSocket = socket(AF_INET, // IPv4
  26. SOCK_STREAM, // 顺序的、可靠的、基于连接的、双向的数据流通信
  27. IPPROTO_TCP// 使用TCP协议
  28. );
  29. if (ConnectSocket == INVALID_SOCKET)
  30. {
  31. printf("Error at socket(): %ld\n", WSAGetLastError());
  32. WSACleanup();
  33. return;
  34. }
  35. // 设置服务端的通信协议、IP地址、端口
  36. clientService.sin_family = AF_INET;
  37. clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
  38. clientService.sin_port = htons( 10000 );
  39. // 连接到服务端
  40. if ( connect(
  41. ConnectSocket, // socket
  42. (SOCKADDR*) &clientService, // 地址
  43. sizeof(clientService) // 地址的大小
  44. ) == SOCKET_ERROR)
  45. {
  46. printf( "Failed to connect(%d)\n",WSAGetLastError() );
  47. WSACleanup();
  48. return;
  49. }
  50. // 准备发送数据
  51. // 如果输入参数是-d,那么发送的数据是“download file”否则是"get information"
  52. if(argc ==2 && (!lstrcmp(argv[1], "-d")))
  53. {
  54. lstrcpyn(sendbuf, "download file", 32);
  55. }
  56. // 向服务端发送数据
  57. bytesSent = send( ConnectSocket, // socket
  58. sendbuf,// 发送的数据
  59. lstrlen(sendbuf)+1,// 数据长度
  60. 0 );// 无标志
  61. if(bytesSent == SOCKET_ERROR)
  62. {
  63. printf( "send error (%d)\n", WSAGetLastError());
  64. closesocket(ConnectSocket);
  65. return;
  66. }
  67. printf( "Bytes Sent: %ld\n", bytesSent );
  68. // 准备接收数据
  69. recvbuf = HeapAlloc(GetProcessHeap(), 0, RECV_BUFFER_SIZE);
  70. // 循环接收
  71. while( bytesRecv != SOCKET_ERROR )
  72. {
  73. //Sleep(50);
  74. bytesRecv = recv( ConnectSocket, // socket
  75. recvbuf, // 接收数据缓存
  76. RECV_BUFFER_SIZE,// 缓存大小
  77. 0 );// 无标志
  78. if ( bytesRecv == 0 )
  79. {
  80. printf( "Connection Closed.\n");
  81. break;
  82. }
  83. // TODO,处理接收的数据,这里只简单的将收到的数据大小显示
  84. printf( "Bytes Recv: %ld\n", bytesRecv );
  85. }
  86. HeapFree(GetProcessHeap(), 0, recvbuf);
  87. WSACleanup();
  88. return;
  89. }

实现服务端

  1. /* 头文件 */
  2. #include <winsock2.h>
  3. #include <ws2tcpip.h>
  4. #include <stdio.h>
  5. /* 常量 */
  6. #define DEFAULT_PORT "10000" // 端口
  7. #define MAX_REQUEST 1024 // 接收数据的缓存大小
  8. #define BUF_SIZE 4096 // 发送数据的缓存大小
  9. /*************************************
  10. * CommunicationThread
  11. * 功能 用于接收和发送数据的线程
  12. * 为每一个连接的客户端创建一个接收发送数据的线程,
  13. * 可以使用多个客户端同时连接到服务端
  14. * 参数 lpParameter,SOKCET
  15. **************************************/
  16. DWORD WINAPI CommunicationThread(
  17. LPVOID lpParameter
  18. )
  19. {
  20. DWORD dwTid = GetCurrentThreadId();
  21. // 获得参数sokcet
  22. SOCKET socket = (SOCKET)lpParameter;
  23. // 为接收数据分配空间
  24. LPSTR szRequest = HeapAlloc(GetProcessHeap(),0, MAX_REQUEST);
  25. int iResult;
  26. int bytesSent;// 用于保存send的返回值,实际发送的数据的大小
  27. // 接收数据
  28. iResult = recv(socket, // socket
  29. szRequest, // 接收缓存
  30. MAX_REQUEST, // 缓存大小
  31. 0);// 标志
  32. if (iResult == 0)// 接收数据失败,连接已经关闭
  33. {
  34. printf("Connection closing...\n");
  35. HeapFree(GetProcessHeap(), 0 ,szRequest);
  36. closesocket(socket);
  37. return 1;
  38. }
  39. else if (iResult == SOCKET_ERROR)// 接收数据失败,socket错误
  40. {
  41. printf("recv failed: %d\n", WSAGetLastError());
  42. HeapFree(GetProcessHeap(), 0 ,szRequest);
  43. closesocket(socket);
  44. return 1;
  45. }
  46. else if (iResult > 0) // 接收数据成功
  47. {
  48. // 显示接收到的数据
  49. printf("\tCommunicationThread(%d)\tBytes received: %d\n", dwTid, iResult);
  50. printf("\tCommunicationThread(%d)\trequest string is (%s)\n",dwTid, szRequest);
  51. // 如果接收到的数据是"download file"
  52. if (lstrcmpi(szRequest, "download file") == 0)
  53. {
  54. // 读取文件download.txt将发送
  55. HANDLE hFile;
  56. LPVOID lpReadBuf; // 发送缓存
  57. DWORD dwBytesRead;
  58. DWORD dwFileSize;
  59. DWORD dwSendFile = 0;
  60. hFile = CreateFile("download.txt",
  61. GENERIC_READ,
  62. FILE_SHARE_READ,
  63. NULL,
  64. OPEN_EXISTING,
  65. FILE_ATTRIBUTE_NORMAL,
  66. NULL);
  67. if (hFile == INVALID_HANDLE_VALUE)
  68. {
  69. printf("\tCommunicationThread\tCould not open file (error %d)\n",
  70. GetLastError());
  71. send(socket, "error", 6, 0);
  72. closesocket(socket);
  73. return 1;
  74. }
  75. // 分配发送数据缓存
  76. lpReadBuf = HeapAlloc(GetProcessHeap(), 0 , BUF_SIZE);
  77. // 获取文件大小
  78. dwFileSize = GetFileSize(hFile, NULL);
  79. // 循环发送
  80. while(1)
  81. {
  82. // 读文件到缓存
  83. if(!ReadFile(hFile, lpReadBuf, BUF_SIZE, &dwBytesRead, NULL))
  84. {
  85. printf("\tCommunicationThread\tCould not read from file (error %d)\n",
  86. GetLastError());
  87. closesocket(socket);
  88. CloseHandle(hFile);
  89. return 1;
  90. }
  91. // 发送读取的文件数据
  92. bytesSent = send(socket, lpReadBuf, dwBytesRead, 0);
  93. if( bytesSent == SOCKET_ERROR)
  94. {
  95. printf("\tCommunicationThread\tsend error %d\n",
  96. WSAGetLastError());
  97. closesocket(socket);
  98. CloseHandle(hFile);
  99. return 1;
  100. }
  101. // 显示发送数据的大小
  102. printf("\tCommunicationThread(%d)\tsend %d bytes\n", dwTid, bytesSent);
  103. // 累加,已经发送的大小
  104. dwSendFile += dwBytesRead;
  105. // 如果所有文件数据都已经发送
  106. if(dwSendFile == dwFileSize)
  107. {
  108. printf("\tCommunicationThread\tFile download ok\n");
  109. break;// 退出循环
  110. }
  111. }
  112. // 释放内存、关闭连接,关闭文件
  113. HeapFree(GetProcessHeap(), 0 , lpReadBuf);
  114. CloseHandle(hFile);
  115. closesocket(socket);
  116. }
  117. // 如果接收到的数据是"get information"
  118. else if (lstrcmpi(szRequest, "get information") == 0)
  119. {
  120. // 发送数据
  121. bytesSent = send(socket, // socket
  122. "this is information", // 数据
  123. lstrlen("this is information")+1, // 数据长度
  124. 0);// 标志
  125. // 判断是否成功
  126. if( bytesSent == SOCKET_ERROR)
  127. {
  128. printf("\tCommunicationThread\tsend error %d\n",
  129. WSAGetLastError());
  130. closesocket(socket);
  131. return 1;
  132. }
  133. printf("\tCommunicationThread(%d)\tsend %d bytes\n",dwTid, bytesSent);
  134. }
  135. else// 收到未知数据
  136. {
  137. printf ("unreferenced request\n");
  138. }
  139. }
  140. // 释放接收数据缓存,关闭socket
  141. HeapFree(GetProcessHeap(), 0 ,szRequest);
  142. closesocket(socket);
  143. return 0;
  144. }
  145. /*************************************
  146. * int __cdecl main(void)
  147. * 功能 socket服务端
  148. **************************************/
  149. int __cdecl main(void)
  150. {
  151. WSADATA wsaData;
  152. SOCKET ListenSocket = INVALID_SOCKET;// 监听socket
  153. SOCKET ClientSocket = INVALID_SOCKET;// 连接socket
  154. struct addrinfo *result = NULL,
  155. hints;
  156. int iResult;// 保存返回结果
  157. // 初始化Winsock,保证Ws2_32.dll已经加载
  158. iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  159. if (iResult != 0)
  160. {
  161. printf("WSAStartup failed: %d\n", iResult);
  162. return 1;
  163. }
  164. // 地址
  165. ZeroMemory(&hints, sizeof(hints));
  166. hints.ai_family = AF_INET;
  167. hints.ai_socktype = SOCK_STREAM;
  168. hints.ai_protocol = IPPROTO_TCP;
  169. hints.ai_flags = AI_PASSIVE;
  170. // 获取主机地址,保证网络协议可用等
  171. iResult = getaddrinfo(NULL, // 本机
  172. DEFAULT_PORT, // 端口
  173. &hints, // 使用的网络协议,连接类型等
  174. &result);// 结果
  175. if ( iResult != 0 )
  176. {
  177. printf("getaddrinfo failed: %d\n", iResult);
  178. WSACleanup();
  179. return 1;
  180. }
  181. // 创建socket,用于监听
  182. ListenSocket = socket(
  183. result->ai_family, // 网络协议,AF_INET,IPv4
  184. result->ai_socktype, // 类型,SOCK_STREAM
  185. result->ai_protocol);// 通信协议,TCP
  186. if (ListenSocket == INVALID_SOCKET)
  187. {
  188. printf("socket failed: %ld\n", WSAGetLastError());
  189. freeaddrinfo(result);
  190. WSACleanup();
  191. return 1;
  192. }
  193. // 绑定到端口
  194. iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
  195. if (iResult == SOCKET_ERROR)
  196. {
  197. printf("bind failed: %d\n", WSAGetLastError());
  198. freeaddrinfo(result);
  199. closesocket(ListenSocket);
  200. WSACleanup();
  201. return 1;
  202. }
  203. printf("bind\n");
  204. freeaddrinfo(result);// reuslt不再使用
  205. // 开始监听
  206. iResult = listen(ListenSocket, SOMAXCONN);
  207. printf("start listen......\n");
  208. if (iResult == SOCKET_ERROR)
  209. {
  210. printf("listen failed: %d\n", WSAGetLastError());
  211. closesocket(ListenSocket);
  212. WSACleanup();
  213. return 1;
  214. }
  215. while (1)
  216. {
  217. // 接收客户端的连接,accept函数会等待,直到连接建立
  218. printf("ready to accept\n");
  219. ClientSocket = accept(ListenSocket, NULL, NULL);
  220. // accept函数返回,说明已经有客户端连接
  221. // 返回连接socket
  222. printf("accept a connetion\n");
  223. if (ClientSocket == INVALID_SOCKET)
  224. {
  225. printf("accept failed: %d\n", WSAGetLastError());
  226. closesocket(ListenSocket);
  227. break;// 等待连接错误,退出循环
  228. }
  229. // 为每一个连接创建一个数据发送的接收线程,
  230. // 使服务端又可以立即接收其他客户端的连接
  231. if(!CreateThread(
  232. NULL,
  233. 0,
  234. CommunicationThread, // 线程函数
  235. (LPVOID)ClientSocket, // 将socket作为参数
  236. 0,
  237. NULL))
  238. {
  239. printf("Create Thread error (%d)", GetLastError());
  240. break;
  241. }
  242. }
  243. // 循环退出,释放DLL。
  244. WSACleanup();
  245. return 0;
  246. }



  1. /* 头文件 */
  2. #include <winsock2.h>
  3. #include <ws2tcpip.h>
  4. #include <stdio.h>
  5. /* 常量 */
  6. #define DEFAULT_PORT "10000" // 端口
  7. #define MAX_REQUEST 1024 // 接收数据的缓存大小
  8. #define BUF_SIZE 4096 // 发送数据的缓存大小
  9. /*************************************
  10. * CommunicationThread
  11. * 功能 用于接收和发送数据的线程
  12. * 为每一个连接的客户端创建一个接收发送数据的线程,
  13. * 可以使用多个客户端同时连接到服务端
  14. * 参数 lpParameter,SOKCET
  15. **************************************/
  16. DWORD WINAPI CommunicationThread(
  17. LPVOID lpParameter
  18. )
  19. {
  20. DWORD dwTid = GetCurrentThreadId();
  21. // 获得参数sokcet
  22. SOCKET socket = (SOCKET)lpParameter;
  23. // 为接收数据分配空间
  24. LPSTR szRequest = HeapAlloc(GetProcessHeap(),0, MAX_REQUEST);
  25. int iResult;
  26. int bytesSent;// 用于保存send的返回值,实际发送的数据的大小
  27. // 接收数据
  28. iResult = recv(socket, // socket
  29. szRequest, // 接收缓存
  30. MAX_REQUEST, // 缓存大小
  31. 0);// 标志
  32. if (iResult == 0)// 接收数据失败,连接已经关闭
  33. {
  34. printf("Connection closing...\n");
  35. HeapFree(GetProcessHeap(), 0 ,szRequest);
  36. closesocket(socket);
  37. return 1;
  38. }
  39. else if (iResult == SOCKET_ERROR)// 接收数据失败,socket错误
  40. {
  41. printf("recv failed: %d\n", WSAGetLastError());
  42. HeapFree(GetProcessHeap(), 0 ,szRequest);
  43. closesocket(socket);
  44. return 1;
  45. }
  46. else if (iResult > 0) // 接收数据成功
  47. {
  48. // 显示接收到的数据
  49. printf("\tCommunicationThread(%d)\tBytes received: %d\n", dwTid, iResult);
  50. printf("\tCommunicationThread(%d)\trequest string is (%s)\n",dwTid, szRequest);
  51. // 如果接收到的数据是"download file"
  52. if (lstrcmpi(szRequest, "download file") == 0)
  53. {
  54. // 读取文件download.txt将发送
  55. HANDLE hFile;
  56. LPVOID lpReadBuf; // 发送缓存
  57. DWORD dwBytesRead;
  58. DWORD dwFileSize;
  59. DWORD dwSendFile = 0;
  60. hFile = CreateFile("download.txt",
  61. GENERIC_READ,
  62. FILE_SHARE_READ,
  63. NULL,
  64. OPEN_EXISTING,
  65. FILE_ATTRIBUTE_NORMAL,
  66. NULL);
  67. if (hFile == INVALID_HANDLE_VALUE)
  68. {
  69. printf("\tCommunicationThread\tCould not open file (error %d)\n",
  70. GetLastError());
  71. send(socket, "error", 6, 0);
  72. closesocket(socket);
  73. return 1;
  74. }
  75. // 分配发送数据缓存
  76. lpReadBuf = HeapAlloc(GetProcessHeap(), 0 , BUF_SIZE);
  77. // 获取文件大小
  78. dwFileSize = GetFileSize(hFile, NULL);
  79. // 循环发送
  80. while(1)
  81. {
  82. // 读文件到缓存
  83. if(!ReadFile(hFile, lpReadBuf, BUF_SIZE, &dwBytesRead, NULL))
  84. {
  85. printf("\tCommunicationThread\tCould not read from file (error %d)\n",
  86. GetLastError());
  87. closesocket(socket);
  88. CloseHandle(hFile);
  89. return 1;
  90. }
  91. // 发送读取的文件数据
  92. bytesSent = send(socket, lpReadBuf, dwBytesRead, 0);
  93. if( bytesSent == SOCKET_ERROR)
  94. {
  95. printf("\tCommunicationThread\tsend error %d\n",
  96. WSAGetLastError());
  97. closesocket(socket);
  98. CloseHandle(hFile);
  99. return 1;
  100. }
  101. // 显示发送数据的大小
  102. printf("\tCommunicationThread(%d)\tsend %d bytes\n", dwTid, bytesSent);
  103. // 累加,已经发送的大小
  104. dwSendFile += dwBytesRead;
  105. // 如果所有文件数据都已经发送
  106. if(dwSendFile == dwFileSize)
  107. {
  108. printf("\tCommunicationThread\tFile download ok\n");
  109. break;// 退出循环
  110. }
  111. }
  112. // 释放内存、关闭连接,关闭文件
  113. HeapFree(GetProcessHeap(), 0 , lpReadBuf);
  114. CloseHandle(hFile);
  115. closesocket(socket);
  116. }
  117. // 如果接收到的数据是"get information"
  118. else if (lstrcmpi(szRequest, "get information") == 0)
  119. {
  120. // 发送数据
  121. bytesSent = send(socket, // socket
  122. "this is information", // 数据
  123. lstrlen("this is information")+1, // 数据长度
  124. 0);// 标志
  125. // 判断是否成功
  126. if( bytesSent == SOCKET_ERROR)
  127. {
  128. printf("\tCommunicationThread\tsend error %d\n",
  129. WSAGetLastError());
  130. closesocket(socket);
  131. return 1;
  132. }
  133. printf("\tCommunicationThread(%d)\tsend %d bytes\n",dwTid, bytesSent);
  134. }
  135. else// 收到未知数据
  136. {
  137. printf ("unreferenced request\n");
  138. }
  139. }
  140. // 释放接收数据缓存,关闭socket
  141. HeapFree(GetProcessHeap(), 0 ,szRequest);
  142. closesocket(socket);
  143. return 0;
  144. }
  145. /*************************************
  146. * int __cdecl main(void)
  147. * 功能 socket服务端
  148. **************************************/
  149. int __cdecl main(void)
  150. {
  151. WSADATA wsaData;
  152. SOCKET ListenSocket = INVALID_SOCKET;// 监听socket
  153. SOCKET ClientSocket = INVALID_SOCKET;// 连接socket
  154. struct addrinfo *result = NULL,
  155. hints;
  156. int iResult;// 保存返回结果
  157. // 初始化Winsock,保证Ws2_32.dll已经加载
  158. iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  159. if (iResult != 0)
  160. {
  161. printf("WSAStartup failed: %d\n", iResult);
  162. return 1;
  163. }
  164. // 地址
  165. ZeroMemory(&hints, sizeof(hints));
  166. hints.ai_family = AF_INET;
  167. hints.ai_socktype = SOCK_STREAM;
  168. hints.ai_protocol = IPPROTO_TCP;
  169. hints.ai_flags = AI_PASSIVE;
  170. // 获取主机地址,保证网络协议可用等
  171. iResult = getaddrinfo(NULL, // 本机
  172. DEFAULT_PORT, // 端口
  173. &hints, // 使用的网络协议,连接类型等
  174. &result);// 结果
  175. if ( iResult != 0 )
  176. {
  177. printf("getaddrinfo failed: %d\n", iResult);
  178. WSACleanup();
  179. return 1;
  180. }
  181. // 创建socket,用于监听
  182. ListenSocket = socket(
  183. result->ai_family, // 网络协议,AF_INET,IPv4
  184. result->ai_socktype, // 类型,SOCK_STREAM
  185. result->ai_protocol);// 通信协议,TCP
  186. if (ListenSocket == INVALID_SOCKET)
  187. {
  188. printf("socket failed: %ld\n", WSAGetLastError());
  189. freeaddrinfo(result);
  190. WSACleanup();
  191. return 1;
  192. }
  193. // 绑定到端口
  194. iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
  195. if (iResult == SOCKET_ERROR)
  196. {
  197. printf("bind failed: %d\n", WSAGetLastError());
  198. freeaddrinfo(result);
  199. closesocket(ListenSocket);
  200. WSACleanup();
  201. return 1;
  202. }
  203. printf("bind\n");
  204. freeaddrinfo(result);// reuslt不再使用
  205. // 开始监听
  206. iResult = listen(ListenSocket, SOMAXCONN);
  207. printf("start listen......\n");
  208. if (iResult == SOCKET_ERROR)
  209. {
  210. printf("listen failed: %d\n", WSAGetLastError());
  211. closesocket(ListenSocket);
  212. WSACleanup();
  213. return 1;
  214. }
  215. while (1)
  216. {
  217. // 接收客户端的连接,accept函数会等待,直到连接建立
  218. printf("ready to accept\n");
  219. ClientSocket = accept(ListenSocket, NULL, NULL);
  220. // accept函数返回,说明已经有客户端连接
  221. // 返回连接socket
  222. printf("accept a connetion\n");
  223. if (ClientSocket == INVALID_SOCKET)
  224. {
  225. printf("accept failed: %d\n", WSAGetLastError());
  226. closesocket(ListenSocket);
  227. break;// 等待连接错误,退出循环
  228. }
  229. // 为每一个连接创建一个数据发送的接收线程,
  230. // 使服务端又可以立即接收其他客户端的连接
  231. if(!CreateThread(
  232. NULL,
  233. 0,
  234. CommunicationThread, // 线程函数
  235. (LPVOID)ClientSocket, // 将socket作为参数
  236. 0,
  237. NULL))
  238. {
  239. printf("Create Thread error (%d)", GetLastError());
  240. break;
  241. }
  242. }
  243. // 循环退出,释放DLL。
  244. WSACleanup();
  245. return 0;
  246. }
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP