我与远程主机有一个 TCP 网络连接。(windows 或 linux)如果远程主机进程终止,recv() 失败,我知道连接已关闭。
但是,有没有办法检查远程主机是否在没有实际接收数据的情况下关闭了连接?
关键是,我想定期检查远程主机是否还活着,但我不想提供或接收任何数据。
先感谢您
需要明确recv()
的是,如果连接已正确关闭,则不应失败。它应该返回 EOF(0 字节)。recv()
将失败是连接被异常关闭。
要检查连接是否已关闭而实际上没有接收到数据,您可能做的最好的事情就是recvmsg()
使用MSG_PEEK
标志调用。只要求一个字节。如果连接已关闭,那么您将收到 EOF(正常关闭)或错误(异常关闭)。如果它还没有关闭,您将获得EAGAIN
(假设您将套接字置于非阻塞模式)或一个字节的数据。所以,是的,从技术上讲,您收到了一个字节的数据,但是由于MSG_PEEK
内核没有记录您所做的事实,所以就好像您没有记录一样。这一切都假设您已经从内核缓冲区中读取了在预期错误可能发生之前到达的流中的所有数据。
当然rakib的评论适用:“如果您不想提供或接收数据,则无法检查远程主机是否处于活动状态。”。这意味着这种方法不会检测到远程主机在没有关闭连接的情况下从网络中消失等场景......
如果您通过 select() 监视套接字的准备读取状态,则 select() 将返回并指示套接字已准备好读取数据。然后,当您尝试 recv() 该数据时, recv() 将失败(如果有错误)或返回 0(如果连接完全关闭,则表示 EOF)。