【问题标题】:How do I properly determine if my client is still connected to the server with C sockets?如何正确确定我的客户端是否仍使用 C 套接字连接到服务器?
【发布时间】:2013-04-19 21:10:07
【问题描述】:

我有一个客户端通过 C Berkeley 套接字连接到服务器。我(尝试)通过使用 MSG_DONTWAIT 和 MSG_PEEK 在套接字上调用 recv() 定期检查连接是否仍然有效。但是,我发现此调用在某些情况下连接断开时(例如,在连接的接口关闭后)和根本没有数据可读取时都会返回 EAGAIN。因此,我无法使用此方法区分连接是否仍然有效。

这是我的功能:

/* return 1 if still connected, 0 otherwise */ 
int still_connected()
{
    int nbytes_recvd = 0;
    char buf[2];
    int err;

    nbytes_recvd = recv(fd,buf,sizeof(buf),MSG_PEEK|MSG_DONTWAIT);
    err = errno;

    if ( nbytes_recvd == 0 )
    {
        return 0;
    }
    else if ( nbytes_recvd < 0 )
    {
       if ( (err == ENOTSOCK) ||
            (err == ENOTCONN) ||
            (err == EINVAL) ||
            (err == ECONNREFUSED) ||
            (err == EBADF) ||
            (err == EOPNOTSUPP) )
       {
          return -1;
       }
    }

    /* nbytes_recvd > 0 or EAGAIN or EWOULDBLOCK */
    /* but I get EAGAIN even if the connection is down because I shut down the    interface */ 
    return 1;
}

如何准确检查连接是否仍然有效?

【问题讨论】:

    标签: c sockets tcp network-programming


    【解决方案1】:

    从 TCP 连接的两个端点之一的角度来看,已经消失的对等点与仍然存在但只是不发送任何数据的对等点之间没有区别。您无法用recv() 或任何其他方法区分这些情况。

    检测对等点是否已关闭、重置、消失或无法访问的唯一方法是发送一些数据并查看会发生什么。有两种选择:

    • 启用 TCP 保持连接 (SO_KEEPALIVE)。这将导致 TCP 偶尔发送一个 keepalive 数据包,并期望来自对等方的 ACK。如果对端无法ACK,那么您可以得知连接已断开。
    • 按照您选择的时间表发送一些实际的应用程序数据(或应用程序级别的保活消息)。同样,如果对端未能响应此数据(或发送后收到套接字错误),您可以得知连接已断开。

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 2021-08-15
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多