SO_KEEPALIVE:检测丢失或终止的连接

问题描述:

我有多个线程,每个线程都有一个客户端应用程序打开的套接字。这些线程中的每一个都会从主线程接收指令,以向客户端发送命令(命令可以运行测试,停止测试,终止会话,退出....)。这些线程是通用的,每个客户端只有一个套接字,并在主线程要求时发送一​​个命令。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。非常感谢。

如果保持活动状态失败,则操作系统将简单地使连接失效,并且对该套接字的任何后续读/写操作都将失败,并显示相应的错误代码。您需要确保您的读/写代码处理错误,以便它可以关闭套接字,如果它尚未这样做的话。

+0

好的,谢谢你,所以我不能依赖让我知道的中断,我只需要每隔一段时间就写一次。然后我会用我自己的心跳。谢谢! – user1777907 2013-05-02 19:09:28