Отже, я прочитав багато інформації про допоміжні дані 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 тощо, і як це можна очікувати у майбутньому.