为什么需要使用 `MSG_WAITALL` FLAG 而不是 `0` FLAG?为什么要与 UDP 一起使用?

Why would one need to use `MSG_WAITALL` FLAG instead of `0` FLAG? Why to use it with UDP?

在编写套接字时,有时会遇到函数的接收系列 (recv, recvfrom, recvmsg)。

这个函数接受一个FLAG参数,我看到网上很多例子都用到了MSG_WAITALL,比如这个example on UDP.

这里是 MSG_WAITALL 标志的定义

MSG_WAITALL (since Linux 2.2)

This flag requests that the operation block until the full request is satisfied. However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or the next data to be received is of a different type than that returned. This flag has no effect for datagram sockets.

因此,我的两个问题:

  1. 为什么需要使用 MSG_WAITALL FLAG 而不是 0 FLAG? (有人可以解释一个问题的场景,使用它可以解决这个问题吗?)
  2. 为什么要和 UDP 一起使用?

正如引用的手册页所提到的,MSG_WAITALL 对 UDP 套接字没有影响,因此没有理由在那里使用它。使用它的示例可能会混淆 and/or 几代 cargo-cult/copy-and-paste 编程的结果。 :)

对于 TCP、OTOH,recv() 的默认行为是阻塞,直到 至少一个字节的数据 可以从套接字复制到用户缓冲区 incoming-data-buffer。当然,TCP 堆栈将尝试提供尽可能多的数据字节,但是如果套接字的 incoming-data-buffer 包含的数据字节少于用户传递给 recv() 的数据字节,则TCP 堆栈将复制尽可能多的字节,return byte-count 表示它实际提供了多少字节。

然而,有些人发现他们更愿意让他们的 recv() 调用保持阻塞,直到他们的 passed-in 数组中的 所有 字节被填充,无论这可能需要多长时间。对于这些人,MSG_WAITALL 标志提供了一种获得该行为的简单方法。 (该标志不是绝对必要的,因为程序员总是可以通过编写一个 while() 循环来模拟该行为,该循环根据需要多次调用 recv(),直到缓冲区中的所有字节都被填充...但它仍然是为了方便起见)