2016-04-28 53 views
0

我必須在多線程linux TCP服務器中實現一個套接字,該套接字在兩個setockopt設置爲SO_RCVTIMEO和SO_SNDTIMEO超時後斷開連接。recv在客戶端崩潰時返回0而不是-1

下面的代碼:

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)語句被正確終止,但是如果客戶端崩潰或終止,來自接收的ret值將永遠在while循環中爲0,而不是 - 1或EWOULDBLOCK。

我該如何解決這個問題?

+0

檢查'0'並處理它?從手冊頁:*「對於TCP套接字,返回值0意味着對等關閉了其連接的一半。」* – user3386109

+0

我認爲當客戶端崩潰時,recv將返回-1。我的錯,謝謝! – gabrielication

+0

順便說一句:'memset(buffer,0,sizeof(buffer));'是貨物崇拜編程。而且,在recv()返回-1之後,errno纔是有用的。在recv()返回> = 0時,errno沒有意義。 – wildplasser

回答

4

確定經過研究後,我發現我的問題是如何使用C套接字進行noob的結果。即使客戶端在套接字上沒有close()函數的情況下崩潰,順便說一句,服務器端的recv將返回0。我認爲它會返回-1或一些錯誤。我的錯。我們可以關閉它並感謝所有人。