27

ブロッキングソケットにデータを非常に高速に書き込むと仮定します[すべてのデータがメモリにあります]。さらに、反対側がデータの読み取りを非常に遅くするとします[各読み取りの間に1秒間スリープするなど]。

この場合、書き込み側で予想される動作は何ですか?反対側が十分なデータを読み取るまで書き込み操作はブロックされますか、それとも書き込みは接続リセットなどのエラーを返しますか?

4

2 に答える 2

37

ブロッキング ソケットの場合、send()すべてのデータがその接続のネットワーク スタックのバッファにコピーされるまで、呼び出しはブロックされます。相手が受け取る必要はありません。このバッファのサイズは実装に依存します。

リモート側が確認応答すると、データはバッファからクリアされます。これは OS の問題であり、実際にデータを読み取るリモートアプリケーションには依存しません。このバッファのサイズも実装に依存します。

リモート バッファがいっぱいになると、ローカル スタックに送信を停止するように指示します。データがリモート バッファから (リモート アプリケーションによって読み取られることによって) クリアされると、リモート システムはローカル システムにさらにデータを送信するように通知します。

どちらの場合も、小規模なシステム (組み込みシステムなど) には数 KB 以下のバッファーがあり、最新のサーバーには数 MB 以上のバッファーがある場合があります。

ローカル バッファに空き領域ができると、send()呼び出しからのデータがさらにコピーされます。そのデータがすべてコピーされると、呼び出しが返されます。

接続が実際にリセットされない限り、「接続リセット」エラーは発生しません (OS から - ライブラリは何でも行う可能性があります)。

だから...ローカルとリモートの両方のバッファサイズを合わせた量のデータを送信するまで、リモートアプリケーションがデータを読み取る速さは問題ではありません。send()その後は、リモート側と同じ速さしかできませんrecv()

于 2013-01-09T18:57:42.237 に答える
7

出力(送信)バッファはいっぱいになるまでいっぱいになりsend()、バッファがパケットをエンキューするのに十分なほど解放されるまでブロックされます。

マニュアルページを送信すると言うように:

メッセージがソケットの送信バッファーに収まらない場合、ソケットが非ブロックI / Oモードになっていない限り、send()は通常ブロックします。

これを見てください:http://manpages.ubuntu.com/manpages/lucid/man2/send.2.html

于 2013-01-09T16:07:05.610 に答える