如果套接字通信的另一端被关闭,为什么recv()不设置errno?

kad*_*ina 2 c sockets linux

我试图使用UDP套接字.在客户端我设置了特定的超时时间,当我调用recv()时,我正在检查返回值,如果它小于0,我正在检查errno是EAGAIN还是EWOULDBLOCK.如果errno不是这两个中的一个,我试图重新连接服务器.现在我需要确定连接的另一端是否关闭.除了检查recv()的返回值等于'0'之外,我还需要检查errno吗?如果套接字的另一端关闭,recv()是否设置了errno?如果不是为什么没有设置errno?

Ant*_*ala 8

UDP没有连接,因此您无法轻易推断出另一端是否已关闭套接字.如果需要连接,则必须使用TCP.

但是,当接收到未打开的UDP端口时,接收器通常会发送ICMP应答; 这可以作为来自recv或的返回值发出信号send; 在Linux上,这可能发生在任何UDP套接字上,而在BSD上,它似乎只适用于"连接"的UDP套接字.

无论如何,你不能在任何一个之间推论出来

  • ICMP对发件人进行防火墙过滤
  • UDP通过防火墙过滤接收器
  • UDP被成功传送到接收器

所以我认为UDP错误的可能信号是"很好的补充",但不能依赖.


TCP非常类似于电话呼叫,而UDP更像是邮箱.如果您发送一封信给没有邮箱的不存在的地址,您可以在2周后收到您的回信,并附上贴纸,说明邮件无法送达.

如果你没有收到你的回信,那么接收者都会收到它,邮递员偷了它,它被分拣机切碎,或者狗吃了这封信; 知道它的唯一方法实际上是成功收到的是接收方发回另一封信确认收据.