2016-04-28 6 views
0

SO_RCVTIMEOとSO_SNDTIMEOで設定された2つのsetsockoptでタイムアウトした後に切断するマルチスレッドLinux TCPサーバーにソケットを実装する必要があります。recvは、クライアントクラッシュ時に-1の代わりに0を返します。

ここでは、コードです:

if(setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))<0){ 
    printf("errore sock option rcvtimeo\n"); 
    exit(EXIT_FAILURE); 
} 

if(setsockopt(receive_sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))<0){ 
    printf("errore sock option sndtimeo\n"); 
    exit(EXIT_FAILURE); 
} 

このソケットに関連するスレッドの産卵後、サーバはこの機能を持つのrecvにとどまる:

int receive_message(int descriptor, char* buffer){ 

    memset(buffer,0,sizeof(buffer)); 
    int ret; 
    while((ret= recv(descriptor, buffer, BUFFER_SIZE-1, MSG_NOSIGNAL))<=0){ 
    if (errno == EWOULDBLOCK || errno == EPIPE){ 
     //stuff... 
     pthread_exit(NULL); 
    } 
    else if (errno == EINTR) continue; 
    else exit(EXIT_FAILURE); 
    } 
    buffer[ret]= '\0'; 

    return ret; 
} 

クライアントがオンラインのままの場合が、ノーとは応答では、if(errno == EWOULDBLOCK || errno == EPIPE)文で正しく終了しますが、クライアントがクラッシュしたり終了したりすると、receiveのret値はwhileループではなく永遠に0になります。 1またはEWOULDBLOCK。

どうすれば解決できますか?

+0

「0」をチェックしてそれを処理しますか?マニュアルページ:*「TCPソケットの場合、戻り値0はピアが接続の半分を閉じたことを意味します」* – user3386109

+0

クライアントがクラッシュすると、recvは-1を返すと考えました。私のせいで、ありがとう! – gabrielication

+0

BTW: 'memset(buffer、0、sizeof(buffer));はカーゴカルトプログラミングです。そして、errnoはrecv()が-1を返した後にのみ有効です。 > 0を返すrecv()では、errnoに意味のある値はありません。 – wildplasser

答えて

4

[OK]を研究した後、私は自分の質問がCソケットを使ってnoobをbeeingした結果であることを発見しました。クライアント側でソケット上でclose()関数を使用せずにクラッシュしても、サーバー側からのrecvは途中で0を返します。私はそれが-1またはいくつかのエラーを返すだろうと思った。私のせい。私たちはこれを閉じて、みんなに感謝することができます。

関連する問題