报电子商务( 网站建设与运营),汽车销售网站模板 cms,建立网站可行性,凡客之家实现了一个基本的 TCP 服务器#xff0c;可以接受多个客户端连接#xff0c;然后持续接收客户端发送的信息#xff0c; 最后将接收到的信息再发送回客户端 。
源码
头文件#xff08;TCPServerTest.h#xff09;
#include iostream
#include winsock2.h可以接受多个客户端连接然后持续接收客户端发送的信息 最后将接收到的信息再发送回客户端 。
源码
头文件TCPServerTest.h
#include iostream
#include winsock2.h
#include ws2tcpip.h#include thread
#include functional // 添加这个头文件以使用 std::bind#include string#pragma comment(lib, ws2_32.lib)class TCPSever {
public:TCPSever(int port);~TCPSever();int createSocket(); //创建套接字int serverPreparation(); //服务器连接准备int startConnectClient(); //接受连接客户端void handleClient(SOCKET clientSocket); //处理客户端int Port;WSADATA wsaData;SOCKET serverSocket;struct sockaddr_in serverAddr, clientAddr;int addrLen sizeof(clientAddr);
}; 源文件TCPServerTest.cpp
#include TCPServerTest.hTCPSever::TCPSever(int port):Port(port)
{// 初始化 Windows Sockets传入的参数MAKEWORD(2, 2)指定使用 Winsock 2.2 版本 成功返回0失败返回非0的错误值if (WSAStartup(MAKEWORD(2, 2), wsaData) ! 0) { //std::cerr Error initializing Winsock\n;}else{createSocket();serverPreparation();startConnectClient();}
}TCPSever::~TCPSever()
{closesocket(this-serverSocket); // 关闭与服务端的连接关闭服务端套接字WSACleanup(); //清理 Winsock 库资源
}int TCPSever::createSocket()
{// 创建套接字this-serverSocket socket(AF_INET, SOCK_STREAM, 0);if (this-serverSocket INVALID_SOCKET) {std::cerr Error creating socket\n;WSACleanup();return 1;}
}int TCPSever::serverPreparation()
{// 设置服务器地址信息this-serverAddr.sin_family AF_INET;this-serverAddr.sin_addr.s_addr INADDR_ANY;this-serverAddr.sin_port htons(Port);// bind 函数 可以绑定套接字到指定地址和端口if (bind(this-serverSocket, (struct sockaddr*)serverAddr, sizeof(serverAddr)) SOCKET_ERROR) {std::cerr Error binding socket\n;closesocket(this-serverSocket);WSACleanup();return 1;}// listen函数开始监听连接参数10表示等待连接队列的最大长度为 10if (listen(this-serverSocket, 10) SOCKET_ERROR) {std::cerr Error listening for connections\n;closesocket(this-serverSocket);WSACleanup();return 1;}std::cout Server listening on port Port std::endl;
}int TCPSever::startConnectClient()
{while (true) //循环接收数据{SOCKET newClientSocket;// 接受客户端连接 accept函数在循环中等待客户端连接一旦有客户端连接会返回一个新的套接字用于与该客户端通信并获取客户端的地址信息newClientSocket accept(this-serverSocket, (struct sockaddr*)clientAddr, addrLen);if (newClientSocket INVALID_SOCKET) {std::cerr Error accepting connection\n;continue;}char clientIP[INET_ADDRSTRLEN];if (inet_ntop(AF_INET, clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN) nullptr) {std::cerr Error converting client IP address\n;}else {std::cout Client: std::string(clientIP) : std::to_string(ntohs(clientAddr.sin_port)) std::endl;std::thread clientThread(std::bind(TCPSever::handleClient, this, newClientSocket)); //连上后和客户端进行数据clientThread.detach();}}
}void TCPSever::handleClient(SOCKET clientSocket)
{const char* welcomeMessage Welcome to the server!\n;send(clientSocket, welcomeMessage, strlen(welcomeMessage), 0); // 向客户端发送信息char buffer[1024];while (true){int bytesRead recv(clientSocket, buffer, sizeof(buffer) - 1, 0);if (bytesRead 0) {buffer[bytesRead] \0;std::cout Received: buffer std::endl;std::string response received: std::string(buffer);send(clientSocket, response.c_str(), response.length(), 0);}else {std::cerr Connection closed by client\n;closesocket(clientSocket);return;}}
}
调用
#include TCPServerTest.hint main() {TCPSever server TCPSever(8888);
}
结果
可以看到服务端可以支持多个客户端连接 客户端代码见
【C】创建TCP客户端-CSDN博客