2013-05-02 47 views
1

我有多個線程,每個線程都有一個客戶端應用程序打開的套接字。這些線程中的每一個都會從主線程接收指令,以向客戶端發送命令(命令可以運行測試,停止測試,終止會話,退出....)。這些線程是通用的,每個客戶端只有一個套接字,並在主線程要求時發送一​​個命令。SO_KEEPALIVE:檢測丟失或終止的連接

客戶端可能會退出或崩潰,或者網絡可能不好。

我一直在想如何弄清楚我的TCP會話已經結束每個客戶端。我發現兩種解決方案在這裏看起來很合適。

1)實現我自己的心跳系統 2)使用keepAlive使用setsockopt。

我試過2),因爲聽起來實施起來更快,但我不確定一件事:請問連接中斷時SO_KEEPALIVE會生成SIGPIPE嗎?我看到它應該是這樣,但從未收到過SIGPIPE。

這是我的代碼的外觀:

void setKeepAlive(int sockfd) { 
    int optval; 

    optval = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &optval, sizeof(optval)); 
    optval = 1; 
    setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, sizeof(optval)); 
} 

而且我的代碼接受連接如下:

for (mNumberConnectedClients = 0; mNumberConnectedClients < maxConnections; ++mNumberConnectedClients) { 
    clientSocket = accept(sockfd, (struct sockaddr *) &client_addr, &clientLength); 

    // set KeepAlive on socket 
    setKeepAlive(clientSocket); 

    pthread_create(&mThread_pool[mNumberConnectedClients], NULL, controlClient, (void*) &clientSocket); 
} 

signal(SIGPIPE, test); 
.... 

而且測試功能:

void test(int n) { 
    printf("Socket broken: %d\n", n); 
} 

測試()永遠不會被觸發。我的理解是否錯誤?我不確定是否生成SIGPIPE。非常感謝。

回答

1

如果保持活動狀態失敗,則操作系統將簡單地使連接失效,並且對該套接字的任何後續讀/寫操作都將失敗,並顯示相應的錯誤代碼。您需要確保您的讀/寫代碼處理錯誤,以便它可以關閉套接字,如果它尚未這樣做的話。

+0

好的,謝謝你,所以我不能依賴讓我知道的中斷,我只需要每隔一段時間就寫一次。然後我會用我自己的心跳。謝謝! – user1777907 2013-05-02 19:09:28