我有一个使用标准socket调用的C++应用程序,我想知道是否可以在不发送或接收任何数据的情况下判断socket是否仍然打开。是否有可靠的select
或ioctlsocket
调用可以使用?
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将其设置为非阻塞状态,然后将其恢复为原来的状态。
一个socket的“打开”并不能帮助您实现端到端的连接。唯一确定您可以与另一端通信的方法是,与另一端进行通信。
在设计任何协议时,您应该考虑实现此检查行为。如果不是您的协议,有时可以以巧妙的方式进行操作(例如通过FTP上传一个非常小而无用的文件来检查FTP端口是否仍然打开)。