listen socket. Где грабли?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 28.08.06 09:56
Оценка:
Помогите советом -- задача из реальной жизни свелась к тестовой: написать 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) при попытке подключения второго

Ожидался нормальный вывод от двух клиентов.
http://denis-zhdanov.blogspot.com
Re: listen socket. Где грабли?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 28.08.06 12:36
Оценка:
Здравствуйте, bolshik, Вы писали:

fixed
http://denis-zhdanov.blogspot.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.