多线程网络通信

发布时间 2023-11-28 14:04:20作者: 无主之地主人

当多客户端同时连接和服务端持续监听时,涉及到多线程,每当有新的客户端连接时,就创建一个新的线程来处理与该客户端的通信,从而允许服务器端同时与多个客户端建立连接。

直接贴代码:

 1 // main.cpp
 2 #include <QCoreApplication>
 3 #include <iostream>
 4 #include <QDebug>
 5 #include <cstring>
 6 #include <WinSock2.h>
 7 #include <thread>
 8 #include <vector>
 9 
10 #pragma comment(lib, "ws2_32.lib")
11 #ifdef _WIN32
12     typedef int socklen_t;
13 #endif
14 
15 void handleClient(int clientSocket)
16 {
17     //处理与客户端的通信
18     char buffer[1024];
19     memset(buffer, 0, sizeof(buffer));
20     recv(clientSocket, buffer, sizeof(buffer), 0);
21     std::cout << "Received from client: " << buffer << std::endl;
22 
23     const char* message = "Hello client!";
24     send(clientSocket, message, strlen(message), 0);
25 
26     //关闭客户端套接字
27     closesocket(clientSocket);
28 }
29 
30 int main(int argc, char *argv[])
31 {
32     QCoreApplication a(argc, argv);
33 
34 #ifdef _WIN32
35     WSADATA wsaData;
36     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
37         std::cerr << "Failed to initialize WinSock" << std::endl;
38         return -1;
39     }
40 #endif
41 
42     //创建套接字
43     int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
44     if (serverSocket == -1)
45     {
46         std::cerr << "Error creating socket" << std::endl;
47         return -1;
48     }
49 
50     //准备地址结构
51     sockaddr_in serverAddress;
52     serverAddress.sin_family = AF_INET;
53     serverAddress.sin_port = htons(8888);
54     serverAddress.sin_addr.s_addr = INADDR_ANY;
55 
56     //绑定套接字
57     if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1)
58     {
59         std::cerr << "Error binding socket" << std::endl;
60         return -1;
61     }
62 
63     //监听连接请求
64     if (listen(serverSocket, 5) == -1)
65     {
66         std::cerr << "Error listening on socket" << std::endl;
67         closesocket(serverSocket);
68         return -1;
69     }
70 
71     std::cout << "Waiting for clients to connect..." << std::endl;
72 
73     //循环接受连接请求
74     std::vector<std::thread> threads;
75     while (true)
76     {
77         //接受连接请求
78         sockaddr_in clientAddress;
79         socklen_t ClientAddressLength = sizeof(clientAddress);
80         int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &ClientAddressLength);
81         if (clientSocket == -1)
82         {
83             std::cerr << "Error accepting connection" << std::endl;
84             continue;
85         }
86 
87         std::cout << "Connection established with client" << std::endl;
88 
89         //创建一个新的线程来处理与客户端的通信
90         threads.emplace_back(std::bind(handleClient, clientSocket));
91     }
92 
93     //关闭服务端套接字
94     closesocket(serverSocket);
95 
96     return a.exec();
97 }