如何从套接字 winsock2

问题描述

嗨,我是 C++ winsock2 套接字的新手,我已经被困在这里一段时间了。

如何从作为参数传递的套接字/文件描述符获取套接字是否已连接、绑定、侦听或关闭

注意:我想在不尝试绑定/连接/侦听/关闭套接字的情况下找出套接字状态,因为这将返回结果并执行操作。示例:如果我想检查套接字是否连接到服务器,我应该尝试连接并获得我不想要的结果。

我正在努力实现这样的目标。

// Using Winsock2 API.
bool isSocketBound(SOCKET s) {
    // Check if socket is bound without attempting to bind.
    // The code which I'm not able to figure out.
    return isBound;
}

// Same goes for the other functions.

提前致谢。

解决方法

如何从作为参数传递的套接字/文件描述符获取套接字是否已连接、绑定、侦听或关闭。

没有单个套接字 API 来查询 SOCKET 的当前状态。但是:

  • getsockname() 会告诉你套接字是否在本地绑定。

  • getpeername() 会告诉您套接字是否已连接到远程对等方。

  • getsockopt()SOL_SOCKET:SO_ACCEPTCONN 选项将告诉您面向连接(即 TCP)SOCKET 是否listen()'ing。>

    或者,如果您尝试在 connect() 的套接字上 listen(),您将收到 WSAEINVAL 错误。如果您尝试在 listen() 的套接字上 connect(),您将收到 WSAEISCONN 错误。

    或者,如果套接字至少在本地绑定,那么您可以使用 getsockname() 获取其本地 IP/端口,然后使用 GetTcpTable()GetTcpTable2() 或 {{3} } 以查明该 IP/端口是否处于 LISTENING 状态。

  • 如果 SOCKET 已在本地关闭,则 SOCKET 一开始就无效,因此您无法查询任何内容。您能做的最好的事情就是在使用完毕后将 SOCKET 设置为 INVALID_SOCKET,然后在需要时检查该条件。另一方面,如果套接字已远程关闭但尚未在本地关闭,则 SOCKET 仍然有效,但无法查询其关闭状态。知道套接字是否已被对等方关闭的唯一方法是 recv() 操作是否报告收到 0 个字节,或者 send() 操作是否因连接错误而失败,或者您是否正在使用 { {1}} 处于异步模式(SOCKETWSAAsyncSelect())并收到 WSAEventSelect() 通知。

注意:我想在不尝试绑定/连接/侦听/关闭套接字的情况下找出套接字状态,因为这将返回结果并执行操作。示例:如果我想检查套接字是否连接到服务器,我应该尝试连接并获得我不想要的结果。

为什么不简单地在自己的代码中跟踪状态?如果您 FD_CLOSE 一个 bind() 并且它成功,那么您知道它是本地绑定的。如果您 SOCKET 并且成功,那么您就知道它已在本地绑定并连接到远程服务器。您应该在 connect() 变量旁边维护一个 state 变量,并随着您在 SOCKET 上执行的每个状态更改操作更新 state