我有多个线程,每个线程都有一个打开的套接字,每个线程都有一个客户端应用程序。这些线程中的每一个都从主线程接收指令以向客户端发送命令(命令可以是运行测试、停止测试、终止会话、退出......)。这些线程是通用的,它们每个客户端只有一个套接字,并且只在主线程要求时发送命令。
客户端可能退出或崩溃,或者网络可能不好。
我一直在尝试查看如何确定每个客户端的 TCP 会话已结束。我发现在这里似乎合适的两个解决方案。
1) 实现我自己的心跳系统 2) 通过 setsockopt 使用 keepAlive。
我已经尝试过 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);
}
test() 永远不会被触发。请问是我的理解有误吗?我不确定是否生成了 SIGPIPE。非常感谢。