Итак, я прочитал много информации о вспомогательных данных unix-stream, но во всей документации отсутствует одна вещь: что должно происходить при частичном чтении?
Предположим, я получаю следующие сообщения в 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, получу ли я вспомогательные данные сразу же, и мне нужно сохранить их для следующего чтения? когда я узнаю, что сообщение на самом деле говорит мне делать с данными? Если я освобожу 20 байтов от msg1 и затем снова вызываю recvmsg, будут ли они одновременно доставлять msg3 и msg4? Вспомогательные данные из msg3 и msg4 объединяются в структуре управляющего сообщения?
Хотя я мог бы написать тестовые программы для экспериментального выяснения этого, я ищу документацию о том, как вспомогательные данные ведут себя в контексте потоковой передачи. Кажется странным, что я не могу найти ничего официального на этом.
Я собираюсь добавить свои экспериментальные результаты, которые я получил из этой тестовой программы:
https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c
Linux 3.2.59, 3.17.6
Похоже, что Linux будет добавлять части вспомогательных сообщений в конец других сообщений, если во время этого вызова recvmsg не нужно было доставлять какую-либо предварительную полезную нагрузку. Как только вспомогательные данные одного сообщения доставляются, он вернет короткое чтение, а не запустит следующее сообщение вспомогательных данных. Итак, в приведенном выше примере чтения я получаю:
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 и т. Д., И как это может произойти в будущем.