【问题标题】:SO_KEEPALIVE: Detecting connection lost or terminatedSO_KEEPALIVE:检测连接丢失或终止
【发布时间】:2013-05-02 18:18:40
【问题描述】:

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

客户端可能退出或崩溃,或者网络可能不好。

我一直在尝试了解如何确定每个客户端的 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。非常感谢。

【问题讨论】:

    标签: sockets keep-alive


    【解决方案1】:

    如果保持连接失败,操作系统将简单地使连接无效,并且该套接字上的任何后续读/写操作都将失败并显示适当的错误代码。您需要确保您的读/写代码正在处理错误,以便它可以关闭套接字(如果尚未这样做)。

    【讨论】:

    • 好的,谢谢,所以我不能指望中断让我知道,我只需要经常写。那我就用自己的心跳。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 2016-09-04
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多