4

Tcp Echo Server の例を読んだことがありますが、不明な点がいくつかあります。

TcpClient client = null;
NetworkStream netStream = null;

try {
  client = listener.AcceptTcpClient(); 
  netStream = client.GetStream();

  int totalBytesEchoed = 0;
  while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) {
    netStream.Write(rcvBuffer, 0, bytesRcvd);
    totalBytesEchoed += bytesRcvd;
  }

  netStream.Close();
  client.Close();
} catch {
  netStream.Close();
}

サーバーがパケットを受信すると (while ループ)、データを rcvBuffer に読み取り、ストリームに書き込みます。

私を混乱させるのは、コミュニケーションにおけるメッセージの時系列順です。netStream.Write() で書き込まれたデータがクライアントにすぐに送信されるか (まだ送信中の場合もあります)、または (クライアントによって) 既にストリームに書き込まれたデータが処理された後にのみ送信されます。

次の質問は、以前のことを明確にするかもしれません: クライアントがストリームに書き込むことによってデータを送信する場合、そのデータはサーバー側のメッセージ キューに移動され、読み取られるのを待っているため、ストリームは実際には「空」になりますか? これは、サーバーがすぐにストリームに書き込むことができる理由を説明します-ストリームからのデータは実際には他の場所にバッファリングされているためです...?

4

3 に答える 3

4

TCP 接続は、原則として全二重です。つまり、2 つの別々のチャネルを扱っているということです。はい、両側が同時に書き込みを行っている可能性があります。

于 2009-10-23T07:18:16.003 に答える
2

ヒント: この例では、メソッド呼び出し NetworkStream.Read がブロックされています。

この本は完全に正しいです。TCP ストリームへの生のアクセスは、余分な「チャンク」を意味するものではありません。たとえば、この例では、一度に 1 バイトを簡単に処理できます。ただし、バッチで読み取りと書き込みを実行すると (通常は公開されたバッファーを使用して)、より効率的な処理が可能になります (多くの場合、システム コールが少なくなるため)。ネットワーク層とネットワーク ハードウェアも独自の形式のバッファを使用します。

Write() から書き込まれたデータが、さらに Reads() が正常に完了する前に実際に書き込まれるという保証は実際にはありません。データが 1 つのレイヤーでフラッシュされたとしても、別のレイヤーでフラッシュされることを意味するわけではなく、データが完全に書き込まれるという保証はまったくありません。クライアントに戻ってきました。ここで、より高いレベルのプロトコルが登場します。

このエコーの例では、データは可能な限り高速に押し出されます。書き込みと読み取りの両方が、基礎となるネットワーク スタック (特に送信バッファーと受信バッファー) に基づいてブロックされ、それぞれに独自の一連のバッファーがあります。

[これはもちろん物事を少し単純化します -- 実際のパケット フローに伝送特性を課す TCP [プロトコル] 自体をいつでも見ることができます。]

于 2009-10-23T06:05:25.010 に答える
1

Read() 操作を実行するとき、技術的には、ネットワークからビットを読み取っていないということは正しいです。基本的に、バッファリングされたデータ (TCP によって受信され、正しい順序で配置されたチャンク) を読み取っています。送信するときは、理論的にはすぐにデータを送信する必要がある Flush() を使用できますが、最新の TCP スタックには、適切なサイズのパケットでデータを収集してネットワークにバーストする方法が少しあります。

Henk Holterman が説明したように、TCP は全二重プロトコル (基盤となるすべてのインフラストラクチャでサポートされている場合) であるため、サーバー/クライアントがデータを読み書きするときは、データの送受信がより重要になります。サーバーがデータを送信するときとは異なり、クライアントはすぐにそれを読み取ります。クライアントは自身のデータを送信してから Read() を実行できます。この場合、データはネットワーク バッファに長く留まり、しばらくすると誰もデータを読みたくないので破棄できます。少なくとも、supa dupa サーバー/クライアント ライブラリ (-.

于 2009-10-23T08:55:24.653 に答える