【问题标题】:Two sockets that ConnectEx to the same IP address and port produce duplicate IOCP eventsConnectEx 连接到相同 IP 地址和端口的两个套接字产生重复的 IOCP 事件
【发布时间】:2018-04-20 11:18:00
【问题描述】:

我有一个使用 IOCP 进行套接字通信的客户端应用程序。我正在使用 ConnectEx 与远程端点建立 TCP 连接(在调用 ConnectEx 之前将套接字绑定到 ADDR_ANY 和端口 0)。

有两个连接到同一个远程端点(相同的 IP 地址和端口号)是有效的。当我使用当前代码测试该条件时,我有两个重叠的 IO 读取操作未完成(每个连接的套接字上一个)来自对 WSARecv() 的调用。每个 WSARecv() 都使用正确的套接字和重叠结构调用。例如:WSARecv(socket1, ...重叠1)和WSARecv(socket2, ...重叠2)。我遇到的问题是,当我从任一远程收到响应时,它会触发两个未完成的重叠操作的完成事件。我的代码仅在两个遥控器具有相同的 IP 地址和端口号时才产生此结果,而不是在有两个唯一的远程地址时产生此结果。这是预期的行为(希望不是)?如果是这样,还有其他方法可以做到这一点吗?

【问题讨论】:

  • 您可能认为您的代码是正确的。但你仍然必须发布它。连接之前的绑定是没有意义的。
  • 对!我会在早上发布。我只是认为这是正确的,因为使用两个重复的远程地址与两个唯一的远程地址时的行为不同。 Microsoft 文档声明使用 ConnectEx() 时需要绑定。我没有尝试在没有绑定的情况下连接。
  • "当我从任一遥控器收到响应时,它会触发两个未完成的重叠操作的完成事件" - 如果您正确分离了OVERLAPPED 每次读取的实例。您的 IOCP 代码中显然存在错误。为 2 个套接字使用相同的远程 IP/端口与此问题无关。套接字连接由协议、本地 IP/端口和远程 IP/端口唯一标识。同一台机器上的多个客户端可以安全地连接到同一个远程 IP/端口,只要它们绑定到不同的本地 IP/端口。
  • ConnectEx() 要求套接字已经绑定(因为它可以重用使用DisconnectEx() 关闭的套接字)。 connect() 和 WSAConnect...() 不这样做,如果尚未绑定,它们将隐式绑定。但是您不能将connect() 与 IOCP 一起使用,请使用WSAConnect...() 或ConnectEx()。

标签: sockets tcp iocp overlapped-io


【解决方案1】:

我正在发布一个答案,尽管它实际上只是对问题发生原因的解释。

我的测试涉及连接到提供数据的远程设备并与之通信。事实证明,它位于 digi 终端服务器的另一端。所以连接路径是:

我的测试计算机(通过 TCP)-> Digi 终端服务器(通过串行)-> 远程设备。

digi 终端服务器基本上将 TCP/IP 转换为串行通信,然后返回。由于串行端没有“连接”的概念,digi 不知道哪个 TCP/IP 连接应该接收串行数据以响应 TCP/IP 请求,因此它将串行数据转发到所有活动连接TCP/IP 端。这就是在我挂起的两个重叠操作上产生 IOCP 触发器的原因。每次向digi发送请求时,它都会从其串行端口发送请求。当终端设备响应时,数字将响应数据转发到我的每个 TCP/IP 连接。

感谢所有对我的问题发表评论的人,但很抱歉占用您的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多