因此,我已经阅读了很多有关unix流辅助数据的信息,但是所有文档中缺少的一件事是,如果部分读取,该怎么办?
假设我正在24字节缓冲区中接收以下消息
msg1 [20 byes] (no ancillary data)
msg2 [7 bytes] (2 file descriptors)
msg3 [7 bytes] (1 file descriptor)
msg4 [10 bytes] (no ancillary data)
msg5 [7 bytes] (5 file descriptors)
第一次调用recvmsg时,我会收到所有msg1(以及部分msg2?操作系统会这样做吗?)如果我获得了msg2的一部分,我是否会立即获取辅助数据,并需要保存以备下次读取当我知道消息实际上告诉我如何处理数据时?如果我从msg1释放20个字节,然后再次调用recvmsg,它将同时提供msg3和msg4吗?来自msg3和msg4的辅助数据是否在控制消息结构中串联在一起?
虽然我可以编写测试程序来通过实验找到答案,但我正在寻找有关辅助数据在流上下文中的行为的文档。我找不到任何官方材料,这似乎很奇怪。
我将在这里添加我的实验结果,这是我从该测试程序获得的:
https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c
Linux 3.2.59、3.17.6
看起来,只要在调用recvmsg的过程中不需要传递先前的辅助有效负载,Linux就会将部分辅助消息附加到其他消息的末尾。一旦传递了一条消息的辅助数据,它将返回短读,而不是开始下一条辅助数据消息。因此,在上面的示例中,我得到的读数是:
recv1: [24 bytes] (msg1 + partial msg2 with msg2's 2 file descriptors)
recv2: [10 bytes] (remainder of msg2 + msg3 with msg3's 1 file descriptor)
recv3: [17 bytes] (msg4 + msg5 with msg5's 5 file descriptors)
recv4: [0 bytes]
BSD 4.4、10.0
BSD比Linux提供了更多的对齐方式,并且在带有辅助数据的消息开始之前立即进行了简短的阅读。但是,它将很乐意将非辅助承载消息附加到辅助承载消息的末尾。因此,对于BSD来说,如果您的缓冲区大于辅助承载的消息,则看起来几乎像数据包一样。我读到的是:
recv1: [20 bytes] (msg1)
recv2: [7 bytes] (msg2, with msg2's 2 file descriptors)
recv3: [17 bytes] (msg3, and msg4, with msg3's 1 file descriptor)
recv4: [7 bytes] (msg5 with 5 file descriptors)
recv5: [0 bytes]
去做:
还是喜欢就知道它是如何发生在老版本的Linux,iOS设备的Solaris等,以及它如何可以预期在未来发生。