Czytałem więc wiele informacji na temat danych pomocniczych strumienia Unix, ale brakuje jednej rzeczy w całej dokumentacji, co powinno się stać, gdy nastąpi częściowy odczyt?
Załóżmy, że otrzymuję następujące komunikaty do 24-bajtowego bufora
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)
Przy pierwszym wywołaniu recvmsg otrzymuję cały msg1 (i część msg2? Czy system operacyjny kiedykolwiek to zrobi?) Jeśli otrzymam część msg2, czy od razu otrzymam dane pomocnicze i muszę je zapisać do następnego odczytu kiedy wiem, co faktycznie mówi mi wiadomość, aby zrobić z danymi? Jeśli zwolnię 20 bajtów z msg1, a następnie ponownie wywołam recvmsg, czy kiedykolwiek dostarczy on msg3 i msg4 w tym samym czasie? Czy dane pomocnicze z msg3 i msg4 są konkatenowane w strukturze komunikatu kontrolnego?
Podczas gdybym mógł pisać programy testowe, aby eksperymentalnie to odkryć, szukam dokumentacji na temat tego, jak zachowują się dane pomocnicze w kontekście transmisji strumieniowej. Dziwne, że nie mogę znaleźć na nim niczego oficjalnego.
Dodam tutaj moje wyniki eksperymentalne, które otrzymałem z tego programu testowego:
https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c
Linux 3.2.59, 3.17.6
Wygląda na to, że Linux dołącza fragmenty komunikatów pomocniczych na końcu innych komunikatów, o ile nie będzie potrzeby dostarczenia wcześniejszej dodatkowej zawartości podczas tego wezwania do recvmsg. Po dostarczeniu danych pomocniczych jednej wiadomości zwróci ona krótki odczyt, a nie rozpocznie następnej wiadomości danych pomocniczych. Tak więc w powyższym przykładzie otrzymane odczyty to:
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 zapewnia więcej wyrównania niż Linux i daje krótki odczyt bezpośrednio przed rozpoczęciem wiadomości z danymi pomocniczymi. Ale z radością dołączy wiadomość o charakterze pomocniczym na końcu komunikatu o charakterze pomocniczym. Tak więc w przypadku BSD wygląda na to, że jeśli twój bufor jest większy niż komunikat zawierający informacje pomocnicze, możesz uzyskać zachowanie podobne do pakietu. Otrzymane odczyty to:
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]
DO ZROBIENIA:
Chciałbym nadal wiedzieć, jak to się dzieje na starszych systemach Linux, iOS, Solaris itp. I jak można się spodziewać w przyszłości.