web-dev-qa-db-ja.com

TCPすべてのパケットでSYN / ACKを送信しますか、それとも最初の接続でのみ送信しますか?

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

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

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

<client connect>
SYN
ACK
DATA

SYN
ACK
DATA

SYN
ACK
DATA
<client disconnect>

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

40
Daniel T.

次のようなものです。

+-------------------------------------------------------+
|     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つの理由から、上の図のようにexactlyではありません。

  • ACKを蓄積できるため、1つのACKでその時点までに受信したすべてを確認できます。つまり、1つのACKで2つ以上の送信を確認できます。
  • ACKは、TCPヘッダーのフラグとフィールドです。ヘッダーを送信するには、少なくともヘッダーに相当する帯域幅に加えて、下位レイヤーが追加するものが必要です。 .soデータを送信する場合は、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の上に構築された一部のアプリケーション層プロトコルには、送受信されたデータを確認するプロトコル固有の方法があります。

75
cHao

SYNは最初に過ぎません。

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

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

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

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

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

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

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

SYN/ACK/FINフラグのこのシーケンスは、接続を確立するものです。

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

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

これについては TCPのウィキペディアエントリ およびもちろんRFCにあります。

10
Don Roby

元のTCP標準RFC 793は最初のSYNパケットでデータを送信することを許可していました。しかし、今日はそうではありません。接続のリクエスターからのスリーウェイハンドシェイクAがBとの接続を要求すると、AはSYNビットが設定されたパケットを送信し、BはACKで応答して受信を確認し、ACK + SYNパケットを送信します。その後送信されます。

Dordalにはこの問題に関する非常に良い説明があります。こちらのリンクをクリックしてください。

0
StacknormalFlow