我有多個線程,每個線程都有一個客戶端應用程序打開的套接字。這些線程中的每一個都會從主線程接收指令,以向客戶端發送命令(命令可以運行測試,停止測試,終止會話,退出....)。這些線程是通用的,每個客戶端只有一個套接字,並在主線程要求時發送一個命令。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。非常感謝。
好的,謝謝你,所以我不能依賴讓我知道的中斷,我只需要每隔一段時間就寫一次。然後我會用我自己的心跳。謝謝! – user1777907 2013-05-02 19:09:28