我只是在清理我们不久前编写的一些代码,并注意到对于 udp 套接字,0 被视为连接关闭。
我很确定这是从等效的 tcp 版本移植相同的 recv 循环的结果。但这让我想知道。recv 可以为 udp 返回 0 吗?在 tcp 上,它表示另一端已关闭连接。udp没有连接的概念所以能返回0吗?如果可以,它的含义是什么?
注意:linux 中的手册页没有区分 udp 和 tcp 的返回码为零,这可能是我们在代码中保留检查的原因。
udp没有连接的概念所以能返回0吗?如果可以的话,这是什么意思
这意味着收到了一个长度为 0 的数据报。来自伟大的UNP:
写入长度为 0 的数据报是可以接受的。在 UDP 的情况下,这会导致一个 IP 数据报包含一个 IP 报头(通常 IPv4 为 20 个字节,IPv6 为 40 个字节)、一个 8 字节的 UDP 报头,并且没有数据。 这也意味着 recvfrom 的返回值 0 对于数据报协议是可以接受的:这并不意味着对等方已关闭连接,就像 TCP 套接字上读取的返回值 0 一样。由于 UDP 是无连接的,因此没有关闭 UDP 连接之类的事情。
在 Linux 中,UDP 套接字上的 recvfrom 可能返回零有两个原因:
1) 接收到零长度数据报,或 2) 在套接字上调用了shutdown
第二种行为很有用,因为它允许您解除阻塞正在套接字上等待的线程。但是,recvfrom 的调用者无法知道套接字是否已关闭或是否接收到零长度数据报。为此,您需要一些其他方式向线程发出套接字已关闭的信号,例如使用共享变量。
第二种行为似乎也与 recv(2) 手册页相矛盾,该手册页是这样说的:
When a stream socket peer has performed an orderly shutdown, the return
value will be 0 (the traditional "end-of-file" return).
显然,它也发生在不是流套接字的 UDP 套接字上。