図5 TCPコネクションの確立と切断手順

切断時も礼儀正しくあいさつ

 次にTCPコネクションの切断手順を見てみよう(図5[拡大表示]参照)。接続時と同様に,TCPは切断するときも礼儀正しくあいさつを交わす。

 具体的には,切断したい側のコンピュータAが,まずFINフラグをオンにしたTCPセグメントを相手Bに送る(1´)。これを受信したコンピュータBは,ACKフラグをオンにしたTCPセグメントを送り返す(2´)。これでAからB方向へのコネクションが切断された状態になる。

 この直後に,コンピュータBはFINフラグをオンにしたTCPセグメントもAへ送る。これはBからA方向へのコネクションを切断する要求だ。そして,この切断要求を受信したコンピュータAがACKフラグをオンにしたTCPセグメントを返すと(3´),TCPコネクションは完全に切断される。

 なお,コネクション確立時と違って,切断手順はいくつかのパターンがある。例えば,RSTフラグを使うと,問答無用で切ることができる。

図7 TCPによるデータの転送の基本的な流れ
シーケンス番号と確認応答番号を使って,データが相手に届いたことを確認しながらデータをやりとりする。

データ転送はACKのキャッチボール

 役割1の最後は,TCPコネクションを確立したあとのデータ転送の基本的なやりとりを見ておこう(図7[拡大表示])。

 データ転送手順は,通信相手からなんらかのTCPセグメントを受け取ったら,その証あかしとしてACKフラグをオンにしたTCPセグメントを返信するだけである。

 ただ,Webブラウザなどのアプリケーションから渡されたデータの大きさは一定ではない。非常に大きい場合もある。こうした場合は,長い巻物を適当な長さで切って,その切れ端を別々に送るイメージになる。しかし,各切れ端は,元の長い巻物のどこに相当するのかという情報を含んでいない。

 したがって,TCPは送信する切れ端(データ)が巻物のどの部分に該当するのかを別の手段で通信相手に伝える必要がある。そのために使うのがヘッダー中の「シーケンス番号」である。 図7のように,データを送り始めたときのシーケンス番号が1001番だったとしよう。すると,TCPは新たに500バイトのデータを送るときに,シーケンス番号として1001を設定して,500バイトのデータを入れて送る(1)。

 一方,データを受信した側(図ではB)は,巻物のどこまでを受け取ったかを送信側に教えるために,ヘッダー中の確認応答番号の領域に,1501と入れてACKフラグをオンにしたTCPセグメントを返信する(2)。これは,「1001番から始まったデータの500バイト分を受け取ったので,次は1501番から下さい」という意味である。そして,Aが続きの1000バイトを送信するときは,シーケンス番号に1501を入れて送信する(3)。

ミニ解説 シーケンス番号を使い切る可能性は?

 シーケンス番号は,32ビット分の大きさなので,232すなわち0~42億9496万7296までの値をとることができる。つまり,約4Gバイトのデータを送るまではシーケンス番号を使い切ることはない。しかし,最近のパソコンではこれくらい大きなファイルを扱うことも珍しくない。もしシーケンス番号が上限まで達したらどうなるか。実は「何も起こらない」。0に戻るだけである。そもそもシーケンス番号の初期値は0からではなく,時刻情報などを基にしてランダムに決められる。したがって,すぐに0に戻ってしまうこともある。なお,実際に4Gバイト以上のデータを送信して,シーケンス番号がひとまわりしても,まず問題は起こらない。