如何检查一个套接字是否仍然打开?

8

我有一个使用标准socket调用的C++应用程序,我想知道是否可以在不发送或接收任何数据的情况下判断socket是否仍然打开。是否有可靠的selectioctlsocket调用可以使用?


你的意思是检查套接字在另一端是否已关闭吗? - jon hanson
是的。我的应用程序运行在Windows上,如果PC休眠,当它恢复时,套接字可能不再有效,因为另一端已经关闭了它(而且由于我的应用程序被挂起,我没有收到任何通知)。 - Rob
2个回答

8
如果您尝试接收一个字节,可能会出现多个错误。如果您使用非阻塞套接字,并尝试在有效连接上进行接收,则会收到错误WSAEWOULDBLOCK。
了解这一点后,我们可以像这样检查非阻塞套接字:
bool connected(SOCKET sock)
{
     char buf;
     int err = recv(sock, &buf, 1, MSG_PEEK);
     if(err == SOCKET_ERROR)
     {
          if(WSAGetLastError() != WSAEWOULDBLOCK)
          {return false;}
     }
     return true;
}

正如您从recv的返回值所看到的,recv可能会因为超时或其他几种错误而断开连接。我相信如果出现错误但仍然连接着,WSAEWOULDBLOCK是它可能返回的唯一值,但您可能需要再次检查返回值列表。此外,在recv中使用的标志(MSG_PEEK)意味着在检查后稍后仍可读取数据,因此您不必担心丢失一个字节的数据。

我认为这只适用于非阻塞套接字,因为它可能会阻塞直到接收到数据。如果您想使用阻塞套接字,您可能需要在此检查之前使用ioctlsocket将其设置为非阻塞状态,然后将其恢复为原来的状态。


对于阻塞套接字,您可以使用select。 - Brian R. Bondy

4

一个socket的“打开”并不能帮助您实现端到端的连接。唯一确定您可以与另一端通信的方法是,与另一端进行通信。

在设计任何协议时,您应该考虑实现此检查行为。如果不是您的协议,有时可以以巧妙的方式进行操作(例如通过FTP上传一个非常小而无用的文件来检查FTP端口是否仍然打开)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接