send()
基礎となるプロトコルについて議論することに関する多くの質問を見てきました。TCP の場合、メッセージが送信されるときにメッセージが分割される可能性があり、受信者が 1 つのアトミック操作でメッセージを取得するという保証がないことを十分に認識しています。この質問では、send()
システム コールがローカル システムのネットワーク層と対話する際の動作についてのみ話しています。
POSIX 標準とsend()
私が読んだドキュメントによると、送信されるメッセージの長さはlength引数で指定されます。長さ lengthの1 つのメッセージをsend()
送信することに注意してください。さらに遠く:
送信するメッセージを保持するためのスペースが送信側ソケットで利用できず、ソケット ファイル記述子が
O_NONBLOCK
設定されていない場合、send()
スペースが利用可能になるまでブロックします。送信するメッセージを保持するためのスペースが送信側ソケットになく、ソケット ファイル記述子がO_NONBLOCK
設定されている場合、send()
失敗します。
-1
この定義では、 send() が (送信されるデータがカーネルでキューに入れられていないことを意味します) またはlength以外の値を返す可能性はありません。これは、メッセージ全体がカーネルでキューに入れられていることを意味します。送信されます。つまり、カーネルで配信するメッセージをローカルでキューに入れることに関しては、send()
アトミックでなければならないように思えます。
- メッセージ全体に対してカーネルのソケット キューに十分なスペースがあり、シグナルが発生しない場合 (通常の場合)、メッセージはコピーされ、lengthが返されます。
- の間に信号が発生した場合、
send()
それは を返さなければなりません-1
。この場合、メッセージの一部をキューに入れることはできません。送信された量がわからないからです。したがって、この状況では何も送信できません。 - メッセージ全体に対してカーネルのソケット キューに十分なスペースがなく、ソケットがブロックされている場合、上記のステートメントに従って、
send()
スペースが利用可能になるまでブロックする必要があります。メッセージはキューに入れられ、lengthsend()
を返します。 - カーネルのソケット キューにメッセージ全体に対して十分なスペースがなく、ソケットが非ブロックの場合は、
send()
失敗し ( が返され-1
)、またはerrno
に設定されます。繰り返しますが、この状況では、メッセージのどの部分もキューに入れることができないことは明らかです。EAGAIN
EWOULDBLOCK
-1
何か不足していますか?send() が値を返すことは可能>=0 && <length
ですか? どんな状況で?非 POSIX/UNIX システムについてはどうですか? Windows のsend()
実装はこれに準拠していますか?