0

接続するクライアントごとにスレッドを生成するサーバーがあります。次に、スレッドはクライアントへのデータの送受信を処理します。これが私のサーバーコードです:

    //////////////
    //  START   //
    /////////////
    while( 1 )
    {
    if( listen(serverSocket, SOMAXCONN) == SOCKET_ERROR ) 
    {
        printf( "Listen failed with error: %ld\n", WSAGetLastError() );
        break;
    }    
        /*
         *  wait for clients...
        */
        clientSocket = accept(serverSocket,
                              (struct sockaddr *)&clientSockAddr,
                              &clientSockAddrLen);


        if( clientSocket == INVALID_SOCKET )
        {
            printf("%d:accept failed\n", WSAGetLastError());
            closesocket(serverSocket);
            WSACleanup();
            return 1;
        }

        printf("Client accepted: IP: %s PORT: %d\n",
            inet_ntoa(clientSockAddr.sin_addr),
            clientSockAddr.sin_port );

        THREADDATA threadData = { clientSocket };
        sprintf_s(threadData.ip, "%s", inet_ntoa(clientSockAddr.sin_addr));

        // spawn a thread for each client
        hthread = CreateThread(
                    NULL,                       // don't inherit handle
                    0,                          // use default size for the executable
                    processClient,
                    (pTHREADDATA)&threadData,   // thread data
                    0,                          // run right away
                    &threadId );
    }

そして、これが私のスレッド関数がどのように見えるかです:

/*
    called by thread for each client
*/
DWORD WINAPI processClient(LPVOID lpParam)
{
    int numBytesRecvd = 0,
        numBytesSent = 0,
        index = 0,
        nLeft = SIZE,
        TOTAL = SIZE;

    char buff[SIZE];
    int run = 1;

    char msg[MSG_SIZE];

    pTHREADDATA td = (pTHREADDATA)lpParam;

    /* keep processing client */
    while (run)
    {
        memset(buff, 0, SIZE);

        numBytesRecvd = recv(td->clientSocket, buff, nLeft, 0);


        /* CLIENT EXITED */
        if( !strcmp(buff, "exit") )
        {

            printf("Client exited!\n");

            run = 0;
        }

        if( numBytesRecvd > 0 )
        {

            printf("< %s\n", buff);

        }

        if (numBytesRecvd == 0)
        {
            printf("Client closed!\n");
            run = 0;
        }

        if( numBytesRecvd == SOCKET_ERROR )
        {
            printf("%d:Recieve error!\n", WSAGetLastError());
            run = 0;
        }
    }

    closesocket(td->clientSocket);
    ExitThread(0);

    return 0;
}

問題:

だから私はサーバーとクライアントを起動します、例えばclient1(win7のコマンドプロンプトから)、すべてがうまくいきます。client1ターミナルで何かを入力すると、サーバーターミナルに出力されます。

次に、別のクライアントclient2を起動すると、サーバーに接続され、入力した内容がサーバーに表示されますが、client1で何かを入力しても、サーバーターミナルに表示されません。

したがって、基本的に、新しいクライアントを起動するたびに、そのクライアントのみがサーバーと通信でき、古いクライアントは通信できません!!! しかし、スレッドは各クライアントを処理し続けると思いましたか?それとも、Windowsのcmdプロンプトがスレッドセーフではないということですか?

4

1 に答える 1

1

ここで2つの考えられる問題を見ることができます:1)スタック上のthreadDataを別のスレッドに渡しています。ヒープに割り当ててから、スレッドに渡す必要があります。2)cli​​entSocketをthreadDataに正しく割り当てていないと思いますが、構造体threadDataのメンバーに割り当てるべきではありませんか?

于 2012-12-17T04:53:14.403 に答える