0

ポートをリッスンして受信データを読み取る単純なソケット デーモン ウィッチを作成しています。クライアントをサーバーから切断することを選択するまでは正常に機能します...その後、無限ループに入ります recv() 最後のパケットが-1にならないことを返します。私の質問は、クライアントが切断されたことを検出して、スレッド/ソケット el を閉じる方法です。

私のスレッドは次のとおりです。

void * SocketHandler(void* lp){
    int * csock = (int*)lp;
    int test = 0;

    char buffer[1024];
    int  buffer_len = 1024;
    int  bytecount,ierr;
    memset(buffer,0,buffer_len);
    while (test == 0)
    {
    if ((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){

        close(csock);
        free(csock);
        test++;
        return 0;
    }
    else
    {
        syslog(LOG_NOTICE,"%s",buffer);

    }
    }
    return 0;
};
4

3 に答える 3

1

きれいに閉じられたソケットはZERO読み取りになりますが、切断された接続は を返すエラー状態-1です。0recvのリターンをキャッチする必要があります。

于 2012-06-12T10:18:42.697 に答える
0

ここで何が起こるかというと、ソケットが死んでいるという事実をエンドが検出しない可能性があります (特に、ソケットから読み取っているだけの場合)。

できることは、ソケットにキープアライブを設定することです。これにより、ソケットの活性の定期的なチェックがオンになります。ただし、素早い反応は期待しないでください。デフォルトのタイムアウトは 20 分程度です。

i = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i));

別のオプションは、独自のキープアライブ通信を行うことです。

于 2012-06-12T10:27:38.850 に答える
0

recv()を返すことにより、ソケットの適切なシャットダウンを示します0(詳細については、マンページを参照してください)。-1エラーが発生した場合にのみ戻ります。正確なエラーを確認する必要errnoがあります。これは、接続が失敗したことを示している場合と示していない場合があるためです ( EINTREAGAINまたはEWOULDBLOCK[非ブロッキング ソケットを想定] は両方とも回復可能なエラーです)。

補足:fdソケットの をポインターとして渡す必要はありvoid *ません。return 0return NULL

于 2012-06-12T10:44:02.633 に答える