Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确确定客户端是否仍使用C套接字连接到服务器?_C_Sockets_Tcp_Network Programming - Fatal编程技术网

如何正确确定客户端是否仍使用C套接字连接到服务器?

如何正确确定客户端是否仍使用C套接字连接到服务器?,c,sockets,tcp,network-programming,C,Sockets,Tcp,Network Programming,我有一个客户端通过C Berkeley套接字连接到服务器。我(尝试)通过使用MSG_DONTWAIT和MSG_PEEK在套接字上调用recv()定期检查连接是否仍然有效。但是,我发现,在某些情况下(例如,在连接的接口关闭后)连接关闭时,以及没有数据可读取时,此调用都返回EAGAIN。因此,我无法区分使用此方法时连接是否仍然有效 以下是我的功能: /* return 1 if still connected, 0 otherwise */ int still_connected() {

我有一个客户端通过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;
}
/*如果仍然连接,则返回1,否则返回0*/
int仍然是连接的()
{
int nbytes_recvd=0;
char-buf[2];
INTERR;
nbytes_recvd=recv(fd、buf、sizeof(buf)、MSG_PEEK | MSG_DONTWAIT);
err=errno;
如果(nbytes_recvd==0)
{
返回0;
}
否则如果(n字节\u记录<0)
{
if((err==ENOTSOCK)||
(err==ENOTCONN)||
(错误==EINVAL)||
(错误==ECONREFUNCED)||
(错误==EBADF)||
(err==EOPNOTSUPP))
{
返回-1;
}
}
/*nbytes_recvd>0或EAGAIN或Ewould块*/
/*但是我得到了EAGAIN,即使连接关闭,因为我关闭了接口*/
返回1;
}

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

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

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

  • 启用TCP KEEPALIVE(
    SO\u KEEPALIVE
    )。这将导致TCP每隔一段时间发送一个keepalive数据包,并期望来自对等方的
    ACK
    。如果对等方未能确认,则您可以了解到连接已断开
  • 按照您选择的时间表发送一些实际的应用程序数据(或应用程序级别的keepalive消息)。类似地,如果对等方未能响应此数据(或在发送数据后出现套接字错误),则可以知道连接已断开