56

着信クライアントをリッスンし、毎秒 1 パケットのデータを送信する TCP サーバーがあります。SYN/ACK パケットは最初の接続でのみ送信されるのではないかと思っていたので、次のようになります。

<client connect>
SYN
ACK
DATA
DATA
DATA
<client disconnect>

それとも、このようにすべてのパケットで送信されますか?

<client connect>
SYN
ACK
DATA

SYN
ACK
DATA

SYN
ACK
DATA
<client disconnect>

また、それが最初のケースである場合、長期間にわたって接続を開いたままにしておくだけで、UDP over TCP の利点はありますか?

4

3 に答える 3

107

それはちょっと好きです:

+-------------------------------------------------------+
|     client           network            server        |
+-----------------+                +--------------------|
|    (connect)    | ---- SYN ----> |                    |
|                 | <-- SYN,ACK -- |     (accepted)     |
|   (connected)   | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when client sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|     (send)      | ---- data ---> |                    |
|                 | <---- ACK ---- |  (data received)   |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when server sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

...and so on, til the connection is shut down or reset

SYN は接続を開始します。通常、接続が確立されているときにのみ表示されます。ただし、TCP 経由で送信されるすべてのデータには ACK が必要です。送信されたすべてのバイトを考慮する必要があります。そうしないと、再送信されます (または、深刻な場合は接続がリセット (クローズ) されます)。

ただし、実際の接続は通常、上の図とまったく同じではありません。これには、次の 2 つの理由があります。

  • ACK が蓄積される可能性があるため、1 つの ACK でその時点までに受信したすべてを確認できます。つまり、1 つの ACK で 2 つ以上の送信を確認できます。
  • ACK は、TCP ヘッダー内の単なるフラグとフィールドです。1つを送信するには、少なくともヘッダーの帯域幅に加えて、下位層が追加するものが必要です。しかし、データセグメントにはすでにすべてが含まれています...したがって、データを送信している場合は、無料でACKを同時に送信できます.

ほとんどの TCP/IP スタックは、再送信や接続のリセットを過度に危険にさらすことなく、ネイキッド ACK の数を減らそうとします。したがって、次のような会話が可能です。

\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|     (send)      | ---- data ---> |   (wait a bit)     |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   |   (dead air)   |                    |
|                 | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

UDP に関しては、SYN と ACK の組み込みの概念はありません。UDP は本質的に「信頼性が低く」、接続指向ではないため、概念はあまり当てはまりません。通常、確認応答はサーバーの応答になります。ただし、UDP の上に構築された一部のアプリケーション層プロトコルには、送受信されたデータを確認するためのプロトコル固有の方法があります。

于 2010-08-30T21:57:09.540 に答える
16

SYNは最初だけです。

ACK は、いずれかの方向の後続のセグメントにあります。ACK は、ウィンドウ サイズも定義します。たとえば、ウィンドウ サイズが 100 の場合、送信者は ACK の受信を予期する前に 100 セグメントを送信できます。たとえば、送信者が 100 個のセグメントを送信したが、セグメント番号 50 が失われた場合、受信者は 1-49 & 51 -100 を取得します。次に、受信者は 50 に対して ACK を送信し (次のセグメントが予期されます)、ウィンドウ サイズを 1 に設定します。送信者は、シーケンス番号 50 の 1 つのセグメントを再送信します。受信者は、101 に対して ACK を送信し、ウィンドウ サイズをより大きな数値に戻します。

どちらも実際には TCP ヘッダーのフィールドであり、データと共に送信できますが、SYN と最初の ACK は通常データなしです。

したがって、あなたが説明するシナリオはどちらもまったく正しくありません。最初のほうが現実に近いですが、SYN の後のすべてのデータ パケットには、ACK と、次に期待されるパケットの番号を識別する確認応答番号フィールドを含める必要があります。

セッションの終了には、FIN フラグ付きパケットとそれに関連する ACK によるハンドシェイクも含まれます。

交換されたシーケンス番号は、失われたパケットを識別し、再試行メカニズムを有効にし、パケットのストリーム全体を正しい順序で再構成するために使用されます。

また、それが最初のケースである場合、長期間にわたって接続を開いたままにしておくだけで、UDP over TCP の利点はありますか?

UDP を使用すると、長期間にわたって接続を開いたままにしておくことはできません。接続がありません。

この一連の SYN/ACK/FIN フラグが接続を確立します。

UDP では、SYN や ACK がないため、通信は一方向であり、配信は保証されず、順序は保持されません。ただし、オーバーヘッドが少ないため、メディアのストリーミングなど、信頼性よりも速度が重要な場合に役立ちます。

これはまだ少し単純化されていますが、現時点で私ができる最善の方法です。

これについては、 TCP に関するウィキペディアのエントリと、もちろん RFC にさらに多くの情報があります。

于 2010-08-30T23:07:02.450 に答える