UNIXストリームの補助データに関する多くの情報を読みましたが、すべてのドキュメントから欠落していることの1つは、部分的な読み取りがある場合に何が起こるかということです。
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の一部を取得しますか?OSはこれを実行しますか?)メッセージが実際にデータを処理するように言っていることを知っているとき?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は補助ベアリングメッセージの一部を他のメッセージの最後に追加するようです。1つのメッセージの補助データが配信されると、次の補助データメッセージを開始するのではなく、短い読み取りを返します。したがって、上記の例では、取得する読み取りは次のとおりです。
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]
TODO:
古いLinux、iOS、Solarisなどでどのように発生するのか、今後どのように発生することが予想されるのかを引き続き知りたいです。