最大データ量には制限がある

 TCP/IPの階層構造に関してもう一つ覚えておきたいのは,上位プロトコルのデータ・サイズは,下位プロトコルのデータ・サイズに制限されるという点だ。

 例えば,下がイーサネットなら,中に入るIPパケットの最大サイズはMACフレームのデータ部分の最大サイズ(1500バイト)になる。同様に,そのIPパケットの中に入るTCPセグメントの最大サイズは,IPパケットのヘッダー分(最小で20バイト)を除いたサイズになる。

 TCP/IPの専門用語では,この1回に運べるIPパケットの最大サイズのことをMTU,TCPセグメントのデータ部分の最大サイズのことをMSSと呼ぶ。特にMSSの方は,このあとでしばしば登場するので覚えておこう。

すべての制御情報はヘッダーにある

 前置きが少し長くなってしまったが,TCPセグメントの中身に話を移そう。

図4 TCPのプロトコル・フォーマットと主なパラメータの意味
 TCPセグメントは,ヘッダー部分とデータ部分に分かれる(図4[拡大表示])。重要なのはヘッダー部分で,通信制御などに使う情報がすべてここに入る。サイズは通常20バイトで,オプションを使うと最大60バイトになる。

 一方のデータ部分には,TCPを利用するアプリケーションのデータが入る。具体的には,Webアクセスで使うHTTPのリクエスト・メッセージや,電子メールの送受信データなどが格納される。TCPは,このデータ部分が壊れていないかを確認するが,中身についてはいっさい関知しない。

制御ビットで相手に状況を伝える

 ヘッダー部分をもう少しじっくり見てみると,通信相手のアプリケーションを識別するために使うポート番号や,送信データの順番などを確認するために使う「シーケンス番号」など,たくさんのフィールドがある。このうち,この役割1で押さえておきたいのが「制御ビット」のフィールドである。

 制御ビットのフィードはTCPセグメントの先頭から数えて107ビット目から始まり,1ビットごとにその領域に名前が付いている。それは順番に,(1)URGアージェント(urgent:緊急確認),(2)ACK(acknowledgement:確認応答),(3)PSH(push:プッシュ),(4)RST(reset:リセット),(5)SYN(synchronize:同期),(6)FIN(finish:終了)――と呼ばれる。それぞれの領域には1か0が入り,1ならば「フラグ(旗)が立つ」という。例えば,ACK領域が1だと「ACKフラグが立っている」あるいは「ACKフラグがオン」という。

 TCPは,これらの6種類のフラグをオンにするかオフにするかで,通信相手にさまざまな情報を伝えるのである。

図5 TCPコネクションの確立と切断手順
図6 TCPの接続状態はWindowsに付属するNETSTATコマンドで確認できる

三つの手順であいさつを交わす

 では,実際にこのフラグをTCPがどのように使っているかを見ていこう。まずは通信相手と接続するときと,切断するときの手順からだ。

 TCPでは,相手との通信に先立ち,必ず仮想的な通信路を作る。こうすることで,ほかの通信と完全に分離され,アプリケーションはあたかも相手と1対1で通信しているように使える。この通信路のことを「TCPコネクション」と呼び,相手とTCPコネクションを作ることを「TCPコネクションを確立する」,「TCPコネクションを張る」などと表現する。

 TCPコネクションを確立するときは,「3WAYスリーウエイハンドシェーク」と呼ぶ特別な手順を実行する(図5[拡大表示])。それは,通信相手BにSYNフラグをオンにしたTCPセグメントを送るところから始まる(1)。これは,AからBの方向へデータを送れる通信路を確保したいという通信許可の要請である。これを受け取ったコンピュータBは,通信を許可するかどうかを判断し,OKなら返事としてACKフラグとSYNフラグがオンのTCPセグメントをAへ返信する(2)。これは,AからBへの通信を許可するとともに,BからAへの通信許可を求めるという意味だ。そして最後に,コンピュータAがACKフラグをオンにしたTCPセグメントをBへ送り,コネクションが確立する(3)。

 このように3回(3WAY)のやりとりが行われるので3WAYハンドシェークと呼ぶわけだ。ちなみにハンドシェークとは「握手」という意味である。

 ここのもう一つのポイントは,一つのTCPコネクションで自分から相手方向への通信路と,相手から自分への通信路の両方,すなわち全2重通信が可能な通信路が作られるという点だ。

 なお,TCPコネクションが確立しているかどうかは,UNIXやWindowsに付属するNETSTAT(ネットスタット)コマンドで簡単に確認できる(図6[拡大表示])。

ミニ解説 PSHやURGフラグのナゾ

 TCPヘッダーの制御ビットのうち,PSHフラグとURGフラグは,今ではちょっとナゾの存在になっている。もともとのRFCでは,PSHフラグは「TCPセグメントを受け取ったら速やかに上位プロトコルへ渡す」,URGフラグは「緊急データ送信のために使う」と規定されている。ところが,TCP/IPのプログラムを開発しているアクセスなどによると「実際にはフラグのチェックはするものの,特別な処理はなにもしていない」(筬島雅之研究員)と言う。守るべきRFCと世の中の実装が必ずしも一致していない一例である。