UDP 套接字的非阻塞连接失败,并显示 EADDRNOTAVAIL?

Non-blocking connect of an UDP socket fails with EADDRNOTAVAIL?

提问人:Mecki 提问时间:10/26/2023 更新时间:10/26/2023 访问量:13

问:

在 macOS 和 iOS 上,我想将 BSD 套接字连接到远程地址 + 端口。代码不会预先知道该套接字是 UDP 还是 TCP 套接字,因此为了防止呼叫阻止出现任何问题,我的代码执行以下操作:connect()

  • 使套接字不阻塞
  • 呼叫目的地connect()
  • 监视套接字是否变得可写 (dispatch_source + DISPATCH_SOURCE_TYPE_WRITE)
  • 当它是可写的时,调用以查看连接是否成功。如果此调用成功,则连接成功。getpeername()
  • 如果调用失败,则调用套接字以获取连接错误。read()

根据这个源 https://cr.yp.to/docs/connect.html,使用 和 是确定非阻塞套接字是否已完成连接、是否成功以及万一不成功时错误是什么的好方法。getpeername()read()

这在大多数时候都很好用。通常连接成功,所以会,有时连接失败,然后会告诉我一个合理的错误(如或等)getpeername()read()no route to hostnetwork down

但是时不时地,我从读取中得到的错误将是()。这是我不明白的错误。我从来没有手动绑定套接字。我只连接了它,所以系统总是可以自由选择它想要用于该套接字的任何接口和源地址;我不在乎。通常,UDP套接字会发生这种情况,该套接字不应以该套接字开头,并且调用应该在后台成功。EADDRNOTAVAILCan't assign requested addressconnect()

为什么 UDP 套接字的非阻塞连接会失败?EADDRNOTAVAIL

iOS macOS 套接字 无阻塞

评论

0赞 Remy Lebeau 10/27/2023
"代码不会预先知道该套接字是 UDP 还是 TCP 套接字“——为什么它不知道?听起来像是糟糕的代码设计。在任何情况下,您始终可以使用 查询套接字的类型。getsockopt(SOL_SOCKET, SO_TYPE)
0赞 Mecki 10/27/2023
@RemyLebeau 由于套接字是在其他地方创建的,因此它甚至可能是原始的,并在不同的进程中创建(因为您需要特殊权限才能创建原始套接字,但您可以通过 IPC 在进程之间传输套接字)。因此,它可能既不是 TCP,也不是 UDP,对于只管理套接字的代码来说,知道这些信息是无关紧要的,因为即使知道,这段代码也不需要采取不同的行动。此外,此信息与我的问题无关,因为我的问题特定于套接字是 UDP 套接字的情况。

答: 暂无答案