代码之家  ›  专栏  ›  技术社区  ›  Rob

如何检查插座是否仍然打开?

  •  7
  • Rob  · 技术社区  · 16 年前

    我有一个C++应用程序,使用标准的套接字调用,我想知道我是否可以告诉一个套接字是否仍然打开,而不发送或接收任何数据。有可靠的方法吗 select ioctlsocket 我能打电话吗?

    2 回复  |  直到 16 年前
        1
  •  8
  •   Brian R. Bondy    15 年前

    如果尝试接收一个字节,则可能会收到多个错误;如果使用非阻塞套接字并尝试在有效连接上接收,则会收到错误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;
    }
    

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

    我相信这只适用于非阻塞套接字,因为它可能会阻塞直到接收到数据。如果要使用阻塞套接字,可能需要将其设置为非阻塞 ioctlsocket 在这张支票之前,把它退回原样。

        2
  •  4
  •   paxdiablo    16 年前

    “打开”的套接字无法帮助您实现端到端连接。要确定你能与另一端沟通,唯一的方法就是与另一端沟通。

    在您设计的任何协议中,都应该考虑实现这种检查行为。如果它不是您的协议,有时会有一些方法偷偷地执行(例如,通过FTP上传一个非常小、无用的文件来检查FTP端口是否仍然打开)。