我正在尝试创建简单的C ++服务器-客户端应用程序,该应用程序允许多个用户连接到服务器。问题在于,在为每个客户端创建新线程之后,recv函数开始使客户端应用崩溃。
这是我的代码,用于为每个连接的客户端创建新线程:
while (ClientSocket = accept(ListenSocket, 0, 0)) {
if (ClientSocket == INVALID_SOCKET) {
printf("\ninvalid client socket", GetLastError());
continue;
}
unsigned threadID;
HANDLE myhandleB = (HANDLE) _beginthreadex(NULL, 0, &Server::receiveMessageThread, (void *) &ClientSocket, 0,
&threadID);
}
这是一种尝试从服务器接收消息的方法:
void waitForMessage() {
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
}
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
}
致电后:
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
客户端应用停止响应。
答案 0 :(得分:1)
您所有的客户端线程都接收到指向 same SOCKET
变量的指针,因此它们将相互踩踏。您需要将SOCKET
的副本传递给每个线程。
如果成功,您还将泄漏HANDLE
返回的_beginthreadex()
,如果失败则泄漏被接受的SOCKET
。
尝试以下方法:
// make sure this is declared as 'static' in the 'Server' class declaration...
unsigned __stdcall Server::receiveMessageThread(void *arg)
{
SOCKET ClientSocket = (SOCKET) arg;
...
closesocket(ClientSocket);
return 0;
}
...
while (true)
{
ClientSocket = accept(ListenSocket, 0, 0);
if (ClientSocket == INVALID_SOCKET)
{
printf("\ninvalid client socket", GetLastError());
continue;
}
unsigned threadID;
HANDLE myhandleB = (HANDLE) _beginthreadex(NULL, 0, &Server::receiveMessageThread, (void *) ClientSocket, 0, &threadID);
if (myhandleB)
CloseHandle(myhandleB);
else
closesocket(ClientSocket);
}