ネットワーク基礎的な事 TCP編

 

昨日IPの事を書いたので

今日はTCPの事書きま〜す

 

まずTCPとは

「接続と切断」、「通信制御」、「アプリケーションとの仲介」という三つの機能に分かれています。

ネットワーク層のIPとセッション層以上のプロトコル( 例:HTTP、FTPTelnet ) の橋渡しをするかたちで動作してます。

簡単に説明するとIPネットワークを介して確実にデータをやりとりするためのプロトコルです。

 

IPネットワークの仕事は、パケットを通信相手に届けること。ただ通信相手にパケットが抜けなく正しい順番で届くことまでは保証していない。

状況によってはネットワークが混雑して、送り出したパケットの一部が届かなかったりする。また、転送経路が変わってしまうこともあるので、送り出した順番通りにデータが届くとは限らないです。

 

TCPはWebブラウザとWebサーバーの間、メーラーとメール・サーバーの間など、IPネットワークを介してアプリケーション同士がきちんとデータをやりとりする必要がある場面で利用されている。

データにTCPヘッダーを付けてTCPパケットを作り、それをIPパケットに収めて相手に送っている。

 

接続と切断とは

通信相手を呼び出して相手と1対1で通信できる仮想的な通信路を確保すること。通信路は「コネクション」と呼ばれ、ほかの通信にじゃまされずに相手との間で、データを確実にキャッチボールできるようにする。このコネクションを確立する手順が「3WAY(スリーウェイ)ハンドシェーク」である。。

 

返事が無ければ再送する

パケットが失われた場合、パケットが失われたことを見つけ出して、失われたパケットを再送する必要がある。そこでTCPスタックは、送信相手からTCPパケットが届いたという確認を送り返してもらう送ったのに返事が来なければ届いていないとみなして、TCPパケットを送り直す。

 

通信制

受信側から転送ペースを調節する

TCPスタックは、受け取ったデータをいったん受信バッファに溜めて届け先となるアプリケーションに引き取ってもらう。際限なくデータが転送されてくると、受信バッファからデータがあふれてしまう。

 そこでTCPでは、連続して受信できるデータ量を「ウインドウ・サイズ」というバイト単位の値でお互いに通知し合うことになっている。一挙に大量のデータが届いたり、送信先のアプリケーションが受信バッファからデータを引き取るのが遅れると、受信バッファの空きが小さくなる。通知するウインドウ・サイズを空きに応じて変更することで、データを受信しきれなくなることを防ぐわけだ。

 

受信側から再送を要求する

まずは「高速再転送」から。パケットの抜けに気付いた受信側が、抜けたデータの前のパケットの確認応答を、正規のものを含め合計3回以上連続して送る。送信側が確認応答を連続して受信したら、再送要求だと判断して、ただちにパケットを再送する。

 

TCPスタックが高速再転送で再送を要求したときに、万一相手が高速再転送に対応していなくいと、相手はわからずに時間切れを待って再送する。効率は上がらないが不具合も起こらない。

 

もう一つのSACK(サック)は、途中のパケットが抜けている場合、受信側が送信側に抜けたパケットを通知する方法だ。飛び飛びに受信したデータを通知することによって、抜けているデータがわかるようになっている。送信側はその内容を見て、抜けている部分だけを送り直す。SACKと高速再転送を併用すれば、受信側が抜けたデータだけ直ちに再送してもらえる。

SACKを使用するときは、TCPコネクションの確立時に双方のTCPスタックの間でSACKを使うかどうかをあらかじめ確認しておく。受信したデータを正確を伝える情報は、TCPヘッダーのオプション部分に書き込む。

SACKはすべてのTCPスタックで使えるわけではない。ただし、Windows 2000以降のWindowsで使えるなど、一般化しつつある。

 

アプリケーションとの仲介

 適切なアプリケーションをポート番号で見分ける 

TCPは、受け取ったデータをどのアプリケーションへ渡せばいいかを判断するために、TCPヘッダーに書かれた「ポート番号」を使う。ちなみにTCPヘッダーにはあて先と送信元のポート番号が書かれている。

TCPはこのあて先ポート番号を見て、受信データをどのアプリケーションに渡すかを判断します。

例えば、あて先ポート番号が「80番」ならWebサーバー、25番だったら電子メールの送信に使うSMTPサーバー、23番ならTelnetサーバー

 

アプリケーションが番号を宣言

ここで誤解しやすいのは、アプリケーションやサーバー・ソフトとポート番号の関係です。ポート番号とアプリケーションの関係はあらかじめ決まっているわけではなく、アプリケーションが起動時などに自分で使うポート番号をTCPに登録します。

 したがって、80番ポートあてに届いたデータでも、80番ポートにWebサーバー・ソフトが登録されていなければ、TCPはWebサーバー・ソフトにこのデータを渡さない。80番ポートを利用するアプリケーションがない場合は、「到達不可能」というメッセージをクライアントへ返すだけである。逆にWebサーバー・ソフトを8080番ポートに割り当てて稼働させれば、TCPは8080番ポートあてに届いたデータをWebサーバー・ソフトに渡す。

 つまり、そのコンピュータあてに80番ポートを指定したTCPセグメントが届いたとき、そのセグメントのデータをWebサーバー・ソフトがほしいなら、Webサーバー・ソフトはTCPに対してあらかじめ80番ポートを使いたいと宣言しておかなければなりません。

 ただ、Webサーバーのような重要なサーバー・ソフトは、世界中で共通のポート番号を使わないと大きな混乱が生じてしまう。Webブラウザなどのクライアント・ソフトが、決まったポート番号(通常は80番)を想定してTCPコネクションをつなぎにいってしますから。そこで、TCP/IPの世界では、0~65535番までのポート番号のうち、1023番までをサーバー・ソフト専用の予約領域として、サーバー・ソフトの種類別に割り当てている。

 

仲介役の実体は「ソケット」

アプリケーションは、TCPで相手と通信したいとき、まずsocket(ソケット)というプログラムを呼び出してソケットを生成する。そして、このソケットに対して、サーバー・ソフトならbind(バインド)という命令を使って自分が待ち受け用として使いたいポート番号を指定する。Webサーバー・ソフトなら、ここで80番ポートを指定することになる。

一方、クライアント・ソフトはconnect(コネクト)という命令を呼び出し、通信相手のIPアドレスとポート番号を指定して、TCPコネクションを確立させる。すると、ソケットがTCP/IPソフトに指定された通信相手とのTCPコネクションを確立するように要求し、実際に確立される。TCPコネクションが確立したあとは、アプリケーションはソケットに対してデータを送れば、通信相手にデータが届き、ソケットから受信データを受けとる。

 

まとめ

TCPは難しいですね

あと最近まったく技術ブログというよりはコピペしてまとめたブログになっているので

気をつけます>_<