前回は、メッセージを作成するブラウザの内部動作についてまとめた。ここでは、TCP/IPのデータを電気信号にしてサーバーに送り出す、プロトコル・スタックとLANアダプタについて説明する。
1 ソケットを作成する
プロトコル・スタックの内部構成
プロトコル・スタックの内部は、役割に応じて4つに分かれている。ネットワーク・アプリケーション、プロトコル・スタック、LANドライバ、LANアダプタであり、上から順にアプリケーション、OS、ドライバ・ソフト、ハードウェアに対応している。また、原則、前の階層が後の階層に作業を依頼するようになっている。
まず、ネットワーク・アプリケーションとは、ブラウザ、メーラー、Webサーバー、メール・サーバーといったプログラムがこれに相当する。アプリケーションの下の部分にはSocketライブラリがあり、その中にはリゾルバが埋め込まれている(Webブラウザはメッセージの作成部隊 ブラウザ内部動作4項を参照)。
その下がOSの内部を表しており、ここにプロトコル・スタックがある。プロトコル・スタックの上部には、TCP(Transmission Control Protocol)というプロトコルを使ってデータ送受信を担当する部分と、UDP(User Datagram Prootocol)というプロトコルを使ってデータ送受信を担当する部分がある。この2つがアプリケーションからの依頼を受けて送受信動作を実行する(詳細は後述6参照)。
その下にはIPプロトコルを使ってパケット送受信動作を制御する部分がある。IPの主な役割は、分割されたデータの塊であるパケットを通信相手まで運ぶことである。IPの中にはICMPとARPというプロトコルを扱う部分が含まれる。ICMP(Internet Control Message Protocol)とは、パケットを運ぶときに発生するエラーを通知したり、制御用のメッセージを通知するときに使うものである。ARP(Address Resolution Protocol)とは、IPアドレスに対応するイーサネットのMACアドレス(IEEEで標準化された同じ形式のアドレス)を調べるときに使う。
IPの下にあるLANドライバとは、LANアダプタのハードウェアを制御するもの。その下にあるLANアダプタが実際の送受信動作を実行する。
ソケットの実体は通信制御用の制御情報
通信制御用の制御情報とは、通信相手のIPアドレスはいくつか、ポート番号は何番か、通信動作はどのような進行状態にあるのかといった情報のことである。プロトコル・スタックは、ソケットに記録された制御情報を参照しながら動いている。例えば、Windowsの場合、netstatというコマンドでソケットの内容を画面に表示できる。
socketを呼び出したときの動き
socketを呼び出した際にプロトコル・スタックが行うことは、以下の4つである。1)ソケットを作る、2)ソケット1つ分のメモリー領域を確保する、3)初期状態であることを記録する、4)そのソケットを示すディスクリプタをアプリケーションに知らせる。
2 サーバーに接続する
接続するとは
接続するとは、データ送受信動作を実行するまでの「準備」作業のことである。その役割は、1)サーバーのIPアドレスやポート番号をプロトコル・スタックに知らせる動作、2)クライアント側からサーバー側に通信動作の開始を伝えること、3)送受信するデータを一時的に格納するメモリー領域の確保、などである。
先頭部分に制御情報を記載したヘッダーを配置する
制御情報には大きく分けて2種類ある。1つはクライアントとサーバーが互いに連絡を取り合うためにやり取りする制御情報であり、もう1つはソケットに記録してプロトコル・スタックの動作を制御するための情報である。
前者の制御情報は、通信動作全体でどんな情報が必要なのか検証され、その内容がTCPプロトコルの仕様で規定されている。例えば、送信元のポート番号や宛先ポート番号など。この制御情報はパケットの先頭部分であるヘッダーに配置される。
後者の制御情報には、アプリケーションから通知された情報、通信相手から受け取った情報、送受信動作の進行情報などが随時記録されていく。そして、プロトコル・スタックは逐一その情報を参照しながら動く。
接続動作の実際
接続動作の第一歩は、TCP担当部分で接続を表す制御情報を記載したTCPヘッダーを作ることである(connect)。このTCPヘッダーの送信元と宛先のポート番号で接続するソケットを特定することができる。そして、そのTCPヘッダーをIP担当部分に渡してクライアントに送り返すよう依頼する。すると、パケットがクライアントに返り、IP担当部分を経由してTCP担当部分に届く。そうしてソケットがデータを送受信できる状態になる。これが大まかな流れである。
3 データを送受信する
プロトコル・スタックにHTTPリクエスト・メッセージを渡す
データ送受信動作は、アプリケーションがwriteを呼び出して送信データをプロトコル・スタックに渡すところから始まる。そして、それを受け取ったプロトコル・スタックが送信動作を実行する、という順番で進む。プロトコル・スタックのポイントは、1)受け取ったデータの中身に何が書いてあるか関知しない、2)受け取ったデータは自分の内部にある送信用バッファ・メモリー領域にためて、アプリケーションが次のデータを渡してくるのを待つ、の2つである。どの程度ためてから送信動作を行うかの判断基準は、以下の2つである。
1)1つのパケットに格納できるデータのサイズであること。MTUとMSSが判断基準。MTUとは、1つのパケットで運ぶことができるデジタル・データの最大長のこと。イーサネットでは、通常1500バイトである。MSSとは、ヘッダーを除いて、1つのパケットで運べるTCPのデータの最大長である。2)タイミング。内部にタイマーを持ち、一定時間以上経過したらパケットを送信するようにすればよい。この2つは相反することもあるため、アプリケーション側で送信のタイミングを制御する余地も残されている。
データが大きいときは分割して送る
アプリケーションのデータは大概大きすぎる(ブログや掲示板の投稿など)。そのため、TCPがIPパケットに収まるサイズに分割し、分割した断片を1つずつパケットに入れて送信する。
パケットが届いたことをACK番号を使って確認
シーケンス番号とACK番号でパケットが受信側に届いたことを確認する(受信確認応答)。シーケンス番号とは、送信側から「○○バイト目から始まるデータを××バイト分送る」と知らせるもの。反対にACK番号とは、受信側から「△△バイト目まで受信した」と答えるものである。このようなしくみがあるため、LANアダプタも、ハブも、ルーターも回復処理をとらなくてよい。エラーを検出したら、そのパケットを捨てるだけでよいのである。
パケット平均往復時間でACK番号の待ち時間を調整
ACK番号が返るのを待つ時間をタイムアウト値という。TCPには待ち時間を動的に変更する方法があり、ACK番号が返ってくる時間を基準にして待ち時間を判断するのである。
ウィンドウ制御方式でACK番号を効率よく管理
ウィンドウ制御とは、パケットを1つ送った後ACK番号を待たずに、連続して複数のパケットを送る方法である。まず、受信側から送信側に受信可能なデータ量を通知することで、受信側の能力を超えてパケットを送らないように実行する。そして、受信処理が終わって受信バッファに空きができたら、TCPヘッダーのウィンドウ・フィールドで送信側に知らせるというものである。なお、この受信可能なデータ量の最大値をウィンドウ・サイズと呼び、TCPをチューニングするパラメータのひとつとして知られている。
ACK番号とウィンドウを相乗り
ACK番号とウィンドウを相乗りさせることで、パケットの数を減らすことができる。ACK番号は受信したデータの末尾がどこなのかを送信側に知らせるものなので、最後のものだけ通知して途中のものは省略しても構わないからである。
HTTPレスポンス・メッセージを受信
まず、受信したデータ断片とTCPヘッダーの内容を調べて、途中でデータが抜けていないかどうか検査し、問題がなければACK番号を送り返す。次に、データ断片を受信バッファに一時保管し、そこで断片をつなぎ合わせて元の姿にデータを復元してからアプリケーションに渡す。そして、アプリケーションにデータを渡したら、タイミングを見計らってウィンドウを送信側に通知するという流れである。
4 サーバーから切断してソケットを抹消
データを送り終わったときに切断
データ送受信を終了するのは、アプリケーションが送信すべきデータを全部送り終わったと判断したときである。例えばWebなら、ブラウザからWebサーバーにリクエスト・メッセージを送って、サーバーがそれに答えてレスポンス・メッセージを送り返し終わったところで終了する。 この場合は、サーバー側が切断フェーズに入る。
ソケットを抹消
サーバーとのやり取りが終わればソケットは不要になるが、誤作動を防ぐためにしばらく待ってから抹消する。誤作動の例は、クライアント側から切断動作が始まり、最後にクライアントが送信したACK番号が消えてしまった場合がある。そのため、数分程度待ってからソケットを抹消するのが一般的である。
データ送受信動作のまとめ
TCPプロトコルでアプリケーションのデータを送受信する動作は、1)ソケット作成、2)クライアントからサーバーに向けての接続動作の実行、3)データ送受信、4)ソケット切断という4つの流れを経る。
5 IPとイーサネットのパケット送受信動作
パケットの基本
パケットは、ヘッダーとデータの2つの部分から構成される。ヘッダーには宛先を表すアドレスなどの制御情報が入っている。そしてその後ろに、依頼元から依頼されたデータが続く。このパケットを運ぶ基本はTCP/IPネットワークにも当てはまる。つまり、1)IPが目的地を見定めて次のIPの中継装置を示し、2)サブネット内にあるイーサネットがその中継装置までパケットを運ぶというしくみを持つ。より具体的には、TCP/IPのパケットにはMACヘッダー(イーサネット用のヘッダー)とIPヘッダー(IP用のヘッダー)があり、役割分担してパケットを運んでいる。
パケット送受信動作の概要
1)TCP担当部分がIP担当部分にパケット送信を依頼するところから始まる。2)依頼を受けたIP担当部分は、内容物を一塊のデジタル・データとみなして、その前に制御情報を記載したヘッダーを付加する(IPヘッダーとMACヘッダー)。3)できあがったパケットをネットワーク用のハードウェアに渡す。4)相手にパケットが届いたら返事が返ってくる。IPがパケットを送受信する動作は、制御パケットだろうが、データのパケットだろうが、パケットの役割によらず皆同じである。
宛先IPアドレスを記載したIPヘッダーを作る
IPヘッダーを作って、TCPヘッダーの前につける。このIPヘッダーのうち、宛先IPアドレスには、通信相手のアドレスをセットする。送信元IPアドレスは送信元となるLANアダプタを判断して、そのアドレスをセットする(経路表については後述)。
イーサネット用のMACヘッダーを作る
IP担当部分は、IPヘッダーをつけたらその前にMACヘッダーをつける。MACヘッダーとは、イーサネットで使うヘッダーで、宛先や送信元のMACアドレスなどが記載されている。また、IP担当部分は経路表のGateway欄の値でパケットを渡す相手を判断する。
ARPで宛先ルーターのMACアドレスを調べる
MACアドレスを調べるときはARPを使う。ARP(Address Resolution Protocol)とは、すべてのルーターに対して、あるIPアドレスを持つ場合に対応するMACアドレスを回答するように働きかけるものである。これは、イーサネットのブロードキャストというしくみを利用している。こうしてパケットを作るところまでがIP担当部分の役割である。
イーサネットの基本
イーサネットとは、多数のコンピュータがいろいろな相手と自由に安価に通信するために考案した通信技術のこと。その原型は、ケーブルを伝わって信号が全体に流れるものである。その後、リピータ・ハブを用いた派生形(10BASE-T)、スイッチング・ハブを用いた形態に置き換わっている。変遷はあれど、1)MACヘッダーの宛先MACアドレスに記載した相手にパケットが届く、2)送信元MACアドレスで送信元を表す、3)イーサ・タイプでパケットの内容物を表す、という3つの性質は今でも変わっていない。
IPパケットを電気や光の信号に変換して送信
イーサネットのパケット送信動作は、電気や光の信号に変換して行われる。この動作を行うのが、LANアダプタである。LANアダプタのROMには、全世界で重複しないよう一元管理されたMACアドレスが製造時に書き込まれている。LANアダプタに書き込まれたMACアドレスは、LANドライバがMAC(Media Access Control)回路にセットする。
パケットに3つの制御用データをつける
MAC回路では、まず送信パケットをバッファ・メモリーから取り出し、先頭にプリアンブルとスタート・フレーム・デリミタという2つのデータ付け加え、末尾にはフレーム・チェック・シーケンス(FCS)というエラー検出用のデータを付け加える。
プリアンブルとは、1と0が交互に現れるビット列が56ビット続くもの。送信するパケットを読み取るときのタイミングをとるために用いる。スタート・フレーム・デリミタとは、最後が11というビット・パターンのこと。これで波形が変わるとともに、それをパケットの開始位置だとみなす。FCSとは、パケットを運ぶ途中に雑音などの影響で波形が乱れ、データが化けてしまった場合にそれを検出するために使うもの。
ハブに向けてパケットを送信
パケット信号を送信する動作には、リピータ・ハブを用いる半2重モードと、スイッチング・ハブを用いる全2重モード(後述)の2つがある。半2重モードとは、LANアダプタのMAC回路が共通形式の信号を作り、PHY(MAU)回路がケーブルに送り出す形式に変換してケーブルに送信するものである。PHY(Physical Layer Device)あるいはMAU(Medium Attachment Unit)とは信号送受信部分であり、イーサネットの信号方式によって呼び名が変わる。100メガビット/以上の高速なイーサネットはPHYと呼ぶ。
返ってきたパケットを受け取る
受信動作の概要は以下の通り。1)受信信号を全部取り込む。2)信号の先頭の波形でタイミングを計り、スタート・フレーム・デリミタが出てきたら、その次のビットからデジタル・データに変換する動作を開始する。3)FCSに問題がなければMACヘッダーの宛先MACアドレスを調べ、LANアダプタを初期化するときにセットした自分のMACアドレスと見比べる。4)完了通知には割り込み(コンピュータをLANアダプタに注意を向けさせること)というしくみを使う。
サーバーからの応答パケットをIPからTCPに渡す
1)IPヘッダー部分のフォーマットや宛先IPアドレスに問題がなければ、パケットをTCP担当部分に渡す。2)TCP担当部分は、IPヘッダーに記載された宛先IPアドレスと送信元IPアドレス、TCPヘッダーに記載された宛先ポート番号と送信元ポート番号という4つの項目を調べ、該当するソケットを探す。3)その状況に応じて適切な動作を実行する。
もし宛先IPアドレスに誤りがあった場合、IP担当部分がICMPというメッセージを使って通信相手にエラーを通知することになっている。主なICMPメッセージには、Echo reply、Destination unreachableなどがある。
6 UDPプロトコルを用いた送受信動作
送り直しの必要がないデータの送信はUDPが効率的
UDP(User Datagram Prootocol)とは、データを全部送り終わった後で受信側から受信確認応答をもらう方法である。データが1つのパケットに収まる程度の長さしかない場合には、TCPよりもUDPの方が効率がいい。
制御用の短いデータ
制御用に行う情報交換は1つのパケットで済んでしまうことが多いため、UDPを使うほうがよい。
音声や動画のデータ
音声や動画のデータは、決められた時間内にデータを届けなければならず、データが多少抜けても致命的な問題にならないという性質がある。このように、送り直しても役に立たない場合、送り直しが必要ない場合には、単純にUDPでデータを送った方が効率がよい。
最後に
データを送受信するとき、OS内部にあるプロトコル・スタックがどう動くのか、そしてLANアダプタでパケットがどのように電気信号に変換されてケーブルから出て行くのかについてまとめた。
プロトコル・スタックがTCPプロトコルを用いてメッセージを送受信する動作は、4つのフェーズに分かれている。1)ソケットを作成する、2)サーバーに接続する、3)データを送受信する、4)サーバーから切断してソケットを抹消する、である。その後、プロトコル・スタックとLANアダプタが連携して、小さな断片に分割したデータをパケットの形にまとめ、それを電気や光の信号に変換してケーブルに送り出す。
次回は、ハブやスイッチ、そしてルーターといった機器を経由して、インターネットに出て行くところまでをまとめる。
![]() |