我试图打开一个多线程服务器,可以同时处理多个客户端。 发生了什么是第一个客户端连接,服务器打印"在",这意味着它进入了交互功能,并且在客户端消息的recv之后,它打印"松饼和"松饼& #34;
简而言之: 客户端1连接 - " in"在服务器窗口中打印(服务器等待来自客户端1的消息)
客户端2连接 - 没有打印
客户端1向服务器发送消息
"松饼"打印,然后" in"打印客户端2的连接。
应该发生的事情是: 客户端1连接 - " in"在服务器窗口中打印
客户端2连接 - " in在服务器窗口中打印
我已经意识到服务器在处理第二个客户端线程之前等待第一个线程完成,因为主函数中的join()。 如果我删除join(),我得到一个运行时错误 - 已经调用abort(R6010) 任何想法如何解决这个问题?
这是我的班级服务器,实际沟通完成了:
typedef struct addrinfo addinfo;
class Server
{
private:
WSADATA _wsaData;
int _iResult;
SOCKET _ListenSocket;
addrinfo* _result;
addrinfo _hints;
int _iSendResult;
char _recvbuf[BUF_LEN];
int _recvbuflen;
std::vector<SOCKET> _ClientSockets;
public:
Server();
bool Setup();
bool CreateSocket();
bool Bind();
bool Listen();
bool Accept();
bool Send();
bool Shutdown();
~Server();
};
Server::Server()
{
_ListenSocket = INVALID_SOCKET;
_ClientSockets.push_back(INVALID_SOCKET);
_result = NULL;
_recvbuflen = BUF_LEN;
}
bool Server::Setup() {
_iResult = WSAStartup(MAKEWORD(2, 2), &_wsaData);
if (_iResult != 0) {
std::cout << "WSAStartup failed with error: " << _iResult << std::endl;
return false;
}
ZeroMemory(&_hints, sizeof(_hints));
_hints.ai_family = AF_INET;
_hints.ai_socktype = SOCK_STREAM;
_hints.ai_protocol = IPPROTO_TCP;
_hints.ai_flags = AI_PASSIVE;
_iResult = getaddrinfo(NULL, DEFAULT_PORT, &_hints, &_result);
if (_iResult != 0) {
std::cout << "getaddrinfo failed with error: " << _iResult << std::endl;
WSACleanup();
return false;
}
return true;
}
bool Server::CreateSocket() {
_ListenSocket = socket(_result->ai_family, _result->ai_socktype, _result->ai_protocol);
if (_ListenSocket == INVALID_SOCKET) {
std::cout << "socket failed with error: " << WSAGetLastError() << std::endl;
freeaddrinfo(_result);
WSACleanup();
return false;
}
return true;
}
bool Server::Bind() {
_iResult = bind(_ListenSocket, _result->ai_addr, (int)_result->ai_addrlen);
if (_iResult == SOCKET_ERROR) {
std::cout << "bind failed with error: " << WSAGetLastError() << std::endl;
freeaddrinfo(_result);
closesocket(_ListenSocket);
WSACleanup();
return false;
}
freeaddrinfo(_result);
return true;
}
bool Server::Listen() {
_iResult = listen(_ListenSocket, SOMAXCONN);
if (_iResult == SOCKET_ERROR) {
std::cout << "listen failed with error: " << WSAGetLastError() << std::endl;
closesocket(_ListenSocket);
WSACleanup();
return false;
}
return true;
}
bool Server::Accept() {
_ClientSockets.push_back(accept(_ListenSocket, NULL, NULL));
if (_ClientSockets[_ClientSockets.size() - 1] == INVALID_SOCKET) {
std::cout << "accept failed with error: " << WSAGetLastError() << std::endl;
closesocket(_ListenSocket);
WSACleanup();
return false;
}
return true;
}
bool Server::Send() {
_iResult = recv(_ClientSockets[_ClientSockets.size() - 1], _recvbuf, _recvbuflen, 0);
std::cout << "muffins" << endl;
if (_iResult > 0) {
_iSendResult = send(_ClientSockets[_ClientSockets.size() - 1], "Accepted", strlen("Accepted"), 0);
if (_iSendResult == SOCKET_ERROR) {
std::cout << "send failed with error: " << WSAGetLastError() << std::endl;
closesocket(_ClientSockets[_ClientSockets.size() - 1]);
WSACleanup();
return false;
}
}
else if (_iResult == 0)
std::cout << "Connection closing..." << std::endl;
else {
std::cout << "recv failed with error: " << WSAGetLastError() << std::endl;
closesocket(_ClientSockets[_ClientSockets.size() - 1]);
WSACleanup();
return false;
}
return true;
}
bool Server::Shutdown() {
_iResult = shutdown(_ClientSockets[_ClientSockets.size() - 1], SD_SEND);
if (_iResult == SOCKET_ERROR) {
std::cout << "shutdown failed with error: " << WSAGetLastError() << std::endl;
closesocket(_ClientSockets[_ClientSockets.size() - 1]);
WSACleanup();
return false;
}
closesocket(_ClientSockets[_ClientSockets.size() - 1]);
WSACleanup();
return true;
}
Server::~Server()
{
}
这是主文件:
void interact(Server* server);
int main() {
Server* server = new Server();
server->Setup();
server->CreateSocket();
server->Bind();
server->Listen();
while (1) {
socket->Accept();
std::thread trd(interact, server);
trd.join();
system("PAUSE");
}
server->Shutdown();
system("PAUSE");
return 0;
}
void interact(Server* server) {
std::cout << "in" << std::endl;
server->Send();
}