如何正确确定我的客户端是否仍通过C套接字连接到服务器? [英] How do I properly determine if my client is still connected to the server with C sockets?

查看:152
本文介绍了如何正确确定我的客户端是否仍通过C套接字连接到服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a client connected to a server via C Berkeley sockets. I (try to) periodically check to see if the connection is still valid by calling recv() on the socket with MSG_DONTWAIT and MSG_PEEK. However, I'm finding that this call returns EAGAIN both when the connection is down in some cases (e.g., after the connection's interface is shut down) and when there is simply no data to read. Hence, there is no way for me to distinguish whether the connection is still valid or not using this method.

这是我的职能:

/* 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;
}

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

How can I accurately check whether the connection is still valid?

推荐答案

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

From the point of view of one of the two endpoints of a TCP connection, there is no difference between a peer that had disappeared and a peer that is still present but simply isn't sending any data. You can't distinguish these situations with recv() or with any other method.

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

The only way to detect if a peer is down, has reset, has disappeared, or has become unreachable, is to send some data and see what happens. There are two options:

  • 启用TCP保持活动(SO_KEEPALIVE).这将导致TCP偶尔发送一次keepalive数据包,并期望来自对等方的ACK.如果对等方未能通过ACK,则可以了解到连接已断开.
  • 按照您选择的时间表发送一些实际的应用程序数据(或应用程序级别的保持活动消息).同样,如果对等方未能响应此数据(或在发送数据后收到套接字错误),则可以得知连接已断开.
  • Enable TCP keepalives (SO_KEEPALIVE). This will cause TCP to send a keepalive packet once in a while and expect an ACK from the peer. If the peer fails to ACK, then you can learn that the connection has been broken.
  • Send some actual application data (or an application-level keepalive message) on a schedule of your choice. Similarily, if the peer fails to respond to this data (or you get a socket error after sending it), you can learn that the connection has been broken.

这篇关于如何正确确定我的客户端是否仍通过C套接字连接到服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆