1

次のコードがありますが、なぜ正しく動作しないのかわかりません。

accept() 呼び出しをループし、指定された

スレッドごとに。

問題は、受け入れが時々ブロックされないことです。

理論的に接続がないときに新しいスレッドを開くプログラム。

それがループです -

    for (dwI = 0;; dwI++)                       //Accept MAX_CLIENTS connections
{
    if(MAX_CLIENTS == dwI)
    {
        dwI=0;
        continue;
    }//if

    if(clients[dwI].bIsInUse)
    {
        continue;
    }//if

    ZeroMemory(&from,sizeof(from));

    if(!AcceptConnection(&ServerSock,&from,&ClientSock))
    {
        PRINT_LE("AcceptConnection",ERROR_ACCEPT_SERVER_CONNECTION);
        closesocket(ServerSock);
        WSACleanup();
        return EXIT_FAILURE;
    }//if

    clients[dwI].ClientSock = ClientSock;

    if(! (clients[dwI].hThread = CreateThread(
            NULL,               //Not inheritable
            0,                  //Default stack size
            ThreadedAcceptTCP,       //ThreadedAccept - function
            &clients[dwI],//Pass pointer to the socket
            0,                  //Start immidiately
            &clients[dwI].dwThreadId                //Save thread id
            )))
    {
        PRINT_GLE("CreateThread");
        closesocket(ServerSock);
        WSACleanup();
        return EXIT_FAILURE;
    }//if

    #ifdef PRINT_STATUS                     //Print status if macro is defined
        printf("Server responce message has been sent.\n");
    #endif
}//for

各関数への独自のラッパーを使用します。

AcceptConnection には以下のコードがあります -

    SOCKET ClientSocket = INVALID_SOCKET;       //Client socket
INT sockaddrSize = sizeof(*pSockAddr);

ClientSocket = accept(          //Create client accepting socket
                *pSock,         //Listen-ed socket
                pSockAddr,      
                &sockaddrSize   
                );

if (INVALID_SOCKET == ClientSocket)     //Check for errors - if any - cleanup and return failure
{
    PRINT_WSAGLE("socket");
    return FAILURE;
}//if

*pClientSock = ClientSocket;        //Pass socket

return SUCCESS;

ブラウザからサーバーに接続すると問題が発生します。

例えば ​​、

最初のスレッドが完了した後 (メインスレッドを一時的に 5 秒間スリープさせることでこれを確認しました)

すべてをクリーンアップし、クライアント ソケットを閉じます。

ただし、2番目の受け入れ呼び出しでは-同じで返されます

SOCKADDR 情報が表示され、余分なスレッドが発生します。

まったく同じデータを受信し、まったく同じデータを送信します。

そして、2回(時にはそれ以上)印刷します:

「サーバー応答メッセージが送信されました。」

なぜこれが起こるのか理解できませんでした。うまくいけば、皆さんが私を助けてくれます.

ありがとう !

4

2 に答える 2

0

これはちょっとした推測ですが、このコード行のロジックについて疑問に思っています。

if(!AcceptConnection(&ServerSock,&from,&ClientSock))

AcceptConnection成功した場合はゼロ以外の値を返し、失敗した場合はゼロの値を返すことを期待しています。ただし、関数はSUCCESS成功すると定数を返します。ただし、一部の Windows ヘッダー ファイルでは、定数 SUCCESS が 0 になるように定義されています。また、失敗を表すさまざまな定数は、ゼロ以外の値です。

独自のコードで SUCCESS と FAILURE を定義している場合でも、次のように戻り値を具体的にチェックすることが理にかなっている場合があります。

if (FAILURE == AcceptConnection(&ServerSock,&from,&ClientSock))
于 2012-12-27T00:09:05.793 に答える
0

考えられる問題の 1 つ: 新しいクライアント SOCKET を割り当てた後に true に設定しているようには見えずclients[dwI].bIsInUse、for ループのロジックが台無しになります。

于 2014-06-20T06:30:49.830 に答える