如何在C中找到套接字连接状态?

Bla*_*bel 26 c network-programming

我有一个TCP连接.服务器只是从客户端读取数据.现在,如果连接丢失,客户端在将数据写入管道(断开的管道)时将收到错误,但服务器仍会侦听该管道.如果连接是UP还是NOT,我能找到任何方法吗?

Sim*_*one 35

您可以像下面这样调用getsockopt:

int error = 0;
socklen_t len = sizeof (error);
int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len);
Run Code Online (Sandbox Code Playgroud)

要测试套接字是否已启动:

if (retval != 0) {
    /* there was a problem getting the error code */
    fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
    return;
}

if (error != 0) {
    /* socket has a non zero error status */
    fprintf(stderr, "socket error: %s\n", strerror(error));
}
Run Code Online (Sandbox Code Playgroud)

  • 它不会检测到一个静默断开的套接字.一个常见的情况是中间的NAT网关超时连接(并且没有人得到通知) - 检测到,正如其他人所说,你必须通过在应用程序协议上实现某种形式的心跳来定期发送内容,或者至少使用TCP_KEEPALIVE (14认同)
  • ofc它没有检测到尚未发生的错误,它不是时间机器 (5认同)
  • strerror(retval)似乎不正确,至少在Linux上是这样.getsockopt的手册页说"成功时返回零.出错时,返回-1,并正确设置errno".所以它应该是strerror(错误) (5认同)
  • 这只返回最后一个错误。它不会检测待处理的错误。 (2认同)

Chr*_*cke 12

只有这样,才能可靠地检测,如果仍然连接插座是定期尝试发送数据.它通常更方便地定义应用程序级别"平"包的客户端忽略,但如果该协议已经specced出无这样的能力,你应该能够配置TCP套接字通过设置要做到这一点SO_KEEPALIVE套接字选项.我已经联系到winsock的文档,但相同的功能应该是适用于所有类BSD插座栈.

  • @Blacklabel Linux(和其他人)允许你设置每个套接字的keepalive超时,参见`man 7 tcp中的TCP_KEEPIDLE套接字选项 (5认同)

bla*_*aze 5

TCP keepalive 套接字选项 (SO_KEEPALIVE) 在这种情况下会有所帮助,并在连接丢失的情况下关闭服务器套接字。

  • 它不会关闭任何东西。它会在下一次发送或接收时出错,但套接字保持打开状态。 (4认同)