2

  MSDN ページを読むと、ソケット トランスポート層に内部バッファーがない場合、Send がブロックされることは明らかです。NoBufferSpaceAvailable エラーが発生したくないので、これは実際には良いことです。私の理解では、トランスポート バッファ スペースは非常に大きいですが、Send がこれらのエラーを防ぐために物事を調整する場合、私は満足しています。

ただし、送信がブロックされる原因が他にあるかどうかは明確ではありません。私の推測では、送信の確認応答を待ってブロックすることはなく、Send はデータをトランスポート バッファーにキューに入れて返すだけです。 

非常に悪いことは、送信が完了するまで特定のソケットが実際に完全にブロックされるまで送信が実際にブロックされる場合です。その場合、1000 件中 1 件の接続速度が遅いと、送信プロセス全体が遅くなる可能性があります。その場合、SendAsync は本当に必須です。

誰もこれについてもっと詳細を持っていますか?

4

2 に答える 2

4

EJPが言うように、送信バッファはACKされていないデータを処理します。つまり、送信するデータは、受信者によってACKされるまでバッファに残ります。これは、パケットに対してACKが到着しない場合に、後でデータを再送信できるようにするためです。

また、EJPが言うように、ACKが受信されるたびに、ACKされたばかりのデータが送信バッファーから削除され、スペースが解放されて、それをさらに送信するために使用できるようになります。

ただし、大量のデータを送信し、ACKの返送が遅い場合(待ち時間が長い、接続のノイズが多い、または途中で切断されただけの場合)、送信バッファがいっぱいになり、最終的には次のようになります。送信バッファスペースが不足しているため、送信がブロックされています。

したがって、ACKされていないデータ自体が直接送信をブロックすることはありませんが、大量のデータを送信し、ACKが返されないことを意味するネットワークの問題がある場合は、はい...ACKされていないデータは最終的にはブロックに送信します。そして、これは正しい振る舞いです。

ACKを受信せずに、データを送信し続けることは望ましくありません。それが必要な場合は、TCPではなくUDPを使用している可能性があります:)

編集:また、接続ごとに1つのスレッドを使用することも珍しくありません。これは、1つの悪い接続が1000に影響を与える可能性があるという特定のケースを回避するためです。また、スケーリングが心配な場合は、とにかく非同期呼び出しを使用する必要があります。

于 2012-09-10T02:55:13.087 に答える
4

TCP 送信は、その送信に対する ACK が受信されるまでブロックされません。それがバッファリングの目的です。送信はバッファリングされ、バッファがいっぱいの間だけブロックされます。一方、非同期的に、TCP はバッファの内容をピアに送信し、ACK されるとそれらを破棄します。

于 2012-09-10T02:00:54.573 に答える