如何正确确定客户端是否仍使用C套接字连接到服务器?
我有一个客户端通过C Berkeley套接字连接到服务器。我(尝试)通过使用MSG_DONTWAIT和MSG_PEEK在套接字上调用recv()定期检查连接是否仍然有效。但是,我发现,在某些情况下(例如,在连接的接口关闭后)连接关闭时,以及没有数据可读取时,此调用都返回EAGAIN。因此,我无法区分使用此方法时连接是否仍然有效 以下是我的功能:如何正确确定客户端是否仍使用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() {
/* 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(
)。这将导致TCP每隔一段时间发送一个keepalive数据包,并期望来自对等方的SO\u KEEPALIVE
。如果对等方未能确认,则您可以了解到连接已断开ACK
- 按照您选择的时间表发送一些实际的应用程序数据(或应用程序级别的keepalive消息)。类似地,如果对等方未能响应此数据(或在发送数据后出现套接字错误),则可以知道连接已断开