我正在尝试使用 UDP 套接字。在客户端上,我设置了特定的超时时间,当我调用 recv() 时,我检查返回值,如果它小于 0,我检查 errno 是 EAGAIN 还是 EWOULDBLOCK。如果 errno 不是这两个之一,我正在尝试重新连接服务器。现在我需要确定连接的另一端是否关闭。除了检查 recv() 的返回值是否等于“0”之外,我还需要检查 errno 吗?如果套接字的另一端关闭,recv() 是否设置 errno?如果不是,为什么没有设置 errno?
最佳答案
UDP 没有连接,因此您无法轻易推断出另一端是否关闭了套接字。如果需要连接,则必须使用 TCP。
但是,经常接收方在连接到未打开的 UDP 端口时发送 ICMP 回复;这可以表示为 recv
或 send
的返回值;在 Linux 上,这可能发生在任何 UDP 套接字上,而在 BSD 上,它似乎只适用于“连接的”UDP 套接字。
在任何情况下,你都不能推导
- 发往发件人的 ICMP 被防火墙过滤
- 发往接收方的 UDP 被防火墙过滤
- UDP 成功传递给接收者
所以我认为 UDP 错误的可能信号是一个“很好的补充”,但不是可以依赖的东西。
TCP 非常类似于电话调用,而 UDP 更像是邮箱。如果您将一封信寄到一个没有邮箱的不存在的地址,您可能会在 2 周后取回您的信件,并贴上说明邮件无法投递的标签。
如果您没有收到您的信件,那么要么是收件人收到了它,要么是 postman 偷了它,要么是它在分拣机中被撕碎了,要么是一只狗吃了这封信;知道它实际上已成功收到的唯一方法是收件人发回另一封确认收据的信。
关于c - 如果套接字通信的另一端关闭,为什么 recv() 不设置 errno?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36604680/