Помогите советом -- задача из реальной жизни свелась к тестовой: написать listen socket, к которому по одному коннектятся клиенту, отсылают три байта, отконнекчиваются. Проблема: при использовании нижеприведенного кода на новых клиентских подключениях(начиная со второго) получаем WSAENOTSOCK после вызова recv(). Клиенты коннектятся строго по очереди.
static SOCKET clientSocket = INVALID_SOCKET;
static HANDLE clientSocketReadyEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
UINT __stdcall threadWrapper(LPVOID param) {
while(true) {
::WaitForSingleObject(clientSocketReadyEvent, INFINITE);
char recvbuf[1024];
int iResult, recvbuflen = 1024;
do {
iResult = recv(clientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
for (int i = 0; i < iResult; ++i) {
printf("\t\t%d\n", recvbuf[i]);
}
} else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed: %d\n", WSAGetLastError());
shutdown(clientSocket,1);
closesocket(clientSocket);
::ResetEvent(clientSocketReadyEvent);
}
} while (iResult > 0);
}
}
...
int main(int argc, char** argv) {
// создание сокета.
int listenResult = listen(serverSocket, 2);
if(SOCKET_ERROR == listenResult) {
printf("Failed listen()");
WSACleanup();
return;
}
while(true) {
// Wait for a client
SOCKET clientTmp = accept(serverSocket, NULL, NULL);
if (INVALID_SOCKET != clientSocket) {
::ResetEvent(clientSocketReadyEvent);
closesocket(clientSocket);
}
clientSocket = clientTmp;
if(clientSocket == INVALID_SOCKET) {
printf("Failed accept()");
WSACleanup();
continue;
}
::SetEvent(clientSocketReadyEvent);
}
closesocket(serverSocket);
WSACleanup();
}
Т.о. образом при запуске сервера, первого клиента, отсылающего байты 1, 2, 3 и второго такого же клиента, получаем в консоли сервера вывод
Bytes received: 1
1
Bytes received: 2
2
3
recv failed: 10054 // (WSAECONNRESET) после отключения первого клиента
recv failed: 10038 // (WSAENOTSOCK) при попытке подключения второго
Ожидался нормальный вывод от двух клиентов.