Baud
プロトコル一覧

TCP

番号付きのセグメントと確認応答で作る、信頼できるバイトストリーム。

SYN のヘッダ

すべての TCP 接続の最初のセグメントを、フィールドごとに見ます。フラグのバイトに注目してください。8 つのスイッチのうち 1 つだけが入っています。

TCP SYN セグメント・24 バイト048121620C811001000220010001000000000005001010000000000000000000000000300000011E811101000000000000000000000000000000000000000000060011000000200000010FA11111010F011110000D211010010EB1110101100000000000000000000020000001004000001000500000101B410110100送信元ポート宛先ポートシーケンス番号確認応答番号データ…予約フラグウィンドウサイズチェックサム緊急ポインタオプション種別オプション長MSS の値フィールドをクリックして中身を見る

フレーム全体

C8 22 00 50 00 00 03 E8 00 00 00 00 60 02 FA F0 D2 EB 00 00 02 04 05 B4: ポート 51234 からポート 80 へ、シーケンス 1000 から始めて、1460 バイトのセグメントを受け取れる、という接続の開始要求です。

フィールド位置例の値意味
送信元ポート0–1 バイト目0xC822 = 51234クライアントのエフェメラルポートです。両者の IP アドレスと宛先ポートとの組(4 つ組)で、この接続を一意に識別します。
宛先ポート2–3 バイト目0x0050 = 80 (HTTP)接続先のサービスです。80 は HTTP(443 なら HTTPS、22 は SSH、25 は SMTP)。
シーケンス番号4–7 バイト目1000 (ISN)送ったバイトには 1 つ 1 つ番号が付きます。SYN では「初期シーケンス番号(ISN)」を知らせます。SYN 自身も番号を 1 つ消費します。実際の OS は ISN をランダムに選びますが、ここでは読みやすさのため 1000 にしています。
確認応答番号8–11 バイト目0(未使用、ACK フラグは 0)「ここまで受け取った。次はこの番号のバイトを送って」という意味です。最初の SYN では意味がないので 0 で、ACK フラグも立てません。
データオフセット12 バイト目の bits 7–46 ワード = 24 バイトヘッダ長(32 ビットワード単位)で、データがどこから始まるかを示します。6 × 4 = 24 バイト。基本ヘッダ 20 バイトにオプション 4 バイトが付いています。
予約12 バイト目の bits 3–00将来のための予約領域で、0 で送ります。
フラグ13 バイト目0x02 = SYNセグメントの種類を示す 8 つの 1 ビットスイッチです。SYN セグメントは SYN だけが立っています。
ウィンドウサイズ14–15 バイト目0xFAF0 = 64240フロー制御です。あと何バイト受け取れるかを示します。送信側は、確認応答の来ていないバイトをこれ以上は送り出してはいけません。
チェックサム16–17 バイト目0xD2EB (✓)疑似ヘッダ(送信元・宛先 IP、プロトコル 6、TCP 長)、ヘッダ、データを対象にします。ここでは実際に計算した 0xD2EB です。IPv4 の UDP と違い、必須です。
緊急ポインタ18–19 バイト目0URG が立っているときだけ意味を持ちます。実際にはほぼ使われません。
オプション種別20 バイト目2 = MSSオプションは「種別・長さ・値」の形です。種別 2 は Maximum Segment Size(最大セグメント長)。
オプション長21 バイト目4オプション全体で 4 バイト(種別・長さ・値 2 バイト)です。
MSS の値22–23 バイト目0x05B4 = 1460「1 セグメントで受け取れる最大のペイロード」です。1460 = Ethernet の MTU 1500 から IP の 20 と TCP の 20 を引いた値です。

概要

IP はパケットを失い、重複させ、順序を入れ替えます。TCP はそれを隠します。すべてのバイトに番号を付け、受信側に届いたものを確認応答させ、届かなかったものを再送し、順序どおりに組み立て直します。アプリケーションからは、バイトを確実に運ぶ筒に見えます。

接続は 3 ウェイハンドシェイクで始まり、FIN で終わります。その間、ウィンドウサイズ(フロー制御)と輻輳ウィンドウ(輻輳制御)が、送信側の速度を決めます。

基本情報

ヘッダ
20 バイト(最大 60)
IP プロトコル番号
6
配送
信頼・順序保証
接続
3 ウェイで開き、4 ウェイで閉じる
識別
(送信元 IP・ポート、宛先 IP・ポート)
規格
RFC 9293

接続を開く

3 つのセグメントで接続を作り、そのあとデータとその確認応答が続きます。シーケンス番号を追ってください。

クライアント192.168.1.20:51234サーバ203.0.113.50:80SYNseq=1000SYN, ACKseq=5000 ack=1001ACKseq=1001 ack=5001PSH, ACKseq=1001 ack=5001 len=100ACKseq=5001 ack=1101CLOSEDLISTENSYN_SENTSYN_RCVDESTABLISHEDESTABLISHED

やり取りの全体

接続を開くのに 3 セグメント。そのあとはすべてのバイトに番号が付き、すべてのセグメントが確認応答されます。この帳簿づけが、信頼できないパケット網を、信頼できるバイトストリームに変えています。

  1. 11. SYN: 話しませんか?

    クライアントが初期シーケンス番号(1000)を選び、接続を開きたいと伝えます。サーバはすでにポート 80 で待ち受けています。

  2. 22. SYN-ACK: はい、こちらの番号はこれです

    サーバは 1001 を確認応答し(SYN が 1000 を消費したので次は 1001 を期待)、同時に自分の初期シーケンス番号 5000 を知らせます。1 つのセグメントで両方をこなします。

  3. 33. ACK: 接続成立

    クライアントが 5001 を確認応答します。両側が相手の開始番号と、相手に声が届いていることを確認できました。接続は成立し、双方向にデータを流せます。

  4. 4最初のデータ: HTTP リクエスト

    クライアントが 100 バイト(たとえば HTTP の GET)を送ります。シーケンス番号 1001〜1100 を占めます。PSH は、すぐアプリケーションに渡すよう求めています。

  5. 5ACK: 100 バイトとも受け取った

    ack=1101 は「1100 までのすべてが届いた、次は 1101 から」の意味です。この ACK が来なければ、クライアントはタイムアウト後にデータを再送します。

接続を閉じる

4 つのセグメント。方向ごとに別々に閉じるためです。

クライアント192.168.1.20:51234サーバ203.0.113.50:80FIN, ACKseq=1101 ack=5001ACKseq=5001 ack=1102FIN, ACKseq=5001 ack=1102ACKseq=1102 ack=5002ESTABLISHEDESTABLISHEDFIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSED

やり取りの全体

FIN、ACK、FIN、ACK。方向ごとに別々に閉じます。TIME_WAIT はクライアントのポートをもうしばらく確保し、この接続の遅れて届く迷子パケットが次の接続を混乱させないようにします。

  1. 11. FIN: 送るものはもうありません

    クライアントは送るデータがなくなったことを伝えます。FIN は番号を 1 つ消費します。受信はまだ続けられます。

  2. 22. ACK: 了解

    サーバが FIN を確認応答します。クライアント側の半分は閉じましたが、サーバ側の半分はまだ開いていて、送り続けられます。

  3. 33. FIN: こちらも終わりです

    サーバのアプリケーションがソケットを閉じると、サーバも自分の FIN を送ります。接続の終了は 2 つの独立した片方向の切断であり、そのため 4 セグメントかかります。

  4. 44. ACK: さようなら

    クライアントがサーバの FIN を確認応答します。サーバはすぐに閉じ、クライアントは TIME_WAIT(約 60 秒、最大セグメント寿命の 2 倍)で待ちます。この ACK が失われてサーバが FIN を再送してきたときに備えるためです。

使われる場面

  • HTTP/1.1・HTTP/2、HTTPS(TLS 付き)、SSH、SMTP、データベース
  • バイトの欠落や順序の乱れが許されないものすべて
  • リアルタイムのメディアには不向き。1 つのセグメントの損失が後続すべてを止めます(ヘッドオブラインブロッキング)

つまずきやすい点

  • シーケンス番号はセグメントではなくバイトを数えます。SYN と FIN はデータを運ばなくても、それぞれ番号を 1 つ消費します。
  • Wireshark は既定で相対シーケンス番号を表示します。実際の ISN はランダムな 32 ビットの値です。
  • SYN に SYN-ACK が返らないのは、ファイアウォールによる破棄かホスト停止のサインです。RST が返れば、ポートが閉じています。
  • 「遅い」接続の多くは、実際には再送タイムアウトを待っている、失われたセグメントです。

出典・規格

  • RFC 9293: Transmission Control Protocol
  • RFC 1071: Internet Checksum

関連するプロトコル