在windows 系统下编写程序,将客户端和服务器端都改为多线程程序,并实现一个服务器能同时 与多个客户端通信。
时间: 2024-02-27 15:55:11 浏览: 141
好的,下面是一个简单的示例程序,演示如何在Windows系统下使用多线程实现一个服务器能同时与多个客户端通信。该程序使用了Winsock2库来实现网络通信,使用了C++11的thread库来实现多线程。
服务端代码:
```c++
#include <iostream>
#include <thread>
#include <vector>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
const int MAX_CLIENTS = 10;
const int BUFFER_SIZE = 1024;
void handleClient(SOCKET clientSocket)
{
char buffer[BUFFER_SIZE];
int recvSize;
while (true)
{
// 接收客户端发送的数据
recvSize = recv(clientSocket, buffer, BUFFER_SIZE, 0);
if (recvSize == 0) // 客户端已关闭连接
{
std::cout << "Client disconnected." << std::endl;
break;
}
else if (recvSize < 0)
{
std::cerr << "Error: recv failed with error code " << WSAGetLastError() << std::endl;
break;
}
// 发送数据回客户端
if (send(clientSocket, buffer, recvSize, 0) < 0)
{
std::cerr << "Error: send failed with error code " << WSAGetLastError() << std::endl;
break;
}
}
// 关闭套接字
closesocket(clientSocket);
}
int main()
{
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
std::cerr << "Error: WSAStartup failed with error code " << result << std::endl;
return 1;
}
// 创建服务器套接字
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
std::cerr << "Error: socket creation failed with error code " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
// 绑定端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(12345);
if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cerr << "Error: bind failed with error code " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 监听端口
if (listen(serverSocket, MAX_CLIENTS) == SOCKET_ERROR)
{
std::cerr << "Error: listen failed with error code " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
std::cout << "Server started, waiting for connections..." << std::endl;
std::vector<std::thread> threads;
SOCKET clientSocket;
sockaddr_in clientAddr;
int addrLen = sizeof(clientAddr);
while (true)
{
// 接受客户端连接请求
clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &addrLen);
if (clientSocket == INVALID_SOCKET)
{
std::cerr << "Error: accept failed with error code " << WSAGetLastError() << std::endl;
continue;
}
// 创建新线程来处理客户端连接
threads.emplace_back(std::thread(handleClient, clientSocket));
}
// 关闭服务器套接字
closesocket(serverSocket);
WSACleanup();
return 0;
}
```
客户端代码:
```c++
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
const int BUFFER_SIZE = 1024;
int main()
{
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
std::cerr << "Error: WSAStartup failed with error code " << result << std::endl;
return 1;
}
// 创建客户端套接字
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET)
{
std::cerr << "Error: socket creation failed with error code " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
// 连接服务器
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(12345);
if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cerr << "Error: connect failed with error code " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "Connected to server." << std::endl;
char buffer[BUFFER_SIZE];
int recvSize;
while (true)
{
// 从标准输入读取数据
std::cin.getline(buffer, BUFFER_SIZE);
// 发送数据到服务器
if (send(clientSocket, buffer, strlen(buffer), 0) < 0)
{
std::cerr << "Error: send failed with error code " << WSAGetLastError() << std::endl;
break;
}
// 接收服务器返回的数据
recvSize = recv(clientSocket, buffer, BUFFER_SIZE, 0);
if (recvSize == 0) // 服务器已关闭连接
{
std::cout << "Server disconnected." << std::endl;
break;
}
else if (recvSize < 0)
{
std::cerr << "Error: recv failed with error code " << WSAGetLastError() << std::endl;
break;
}
// 在标准输出中显示服务器返回的数据
buffer[recvSize] = '\0';
std::cout << "Server: " << buffer << std::endl;
}
// 关闭客户端套接字
closesocket(clientSocket);
WSACleanup();
return 0;
}
```
这个示例程序中,服务端使用一个while循环不断接受客户端连接请求,并为每个客户端连接创建一个新的线程来处理通信。客户端则在一个while循环中不断从标准输入读取数据,并将数据发送到服务器,然后等待服务器返回数据并在标准输出中显示。
阅读全文