【TCPプロトコル】

TCPプロトコルは、送信側と受信側の間で、確実にデータを交換する役割を担当しています。
TCPプロトコルは、以下の処理を担当しています。

①  相手が通信可能かどうかを確認する。(コネクションの確立)
② 相手にデータが届いたかどうかを確認する。(ACKによる到達確認)
③  相手の処理能力に合わせてデータサイズを調整する。(ウインドウサイズを利用したフロー制御)

コネクションの確立

TCPは、コネクション型通信を行います。
コネクション型とは、ホスト間で相互の状況を確認してからデータを送り、データの到着を確認してから次のデータを送るようにして、通信を確実に行う方法です。
(IP単独での通信、またUDPはコネクションレス型であり、このような通信の保証はありません)。

データ送信に先立ち、ホストA とホストB の間で通信の準備をする必要があります。
それをコネクションの確立といいます。

まず、ホストA はホストB に SYN (シン SYNchronization:同期) を送ります。
ホストB はそれを受けて要求を受け付けた ACK (アック ACKnowledgement:確認応答) と SYN を返信します。

それを受けてホストA は ACK を送ります。
これで送信する準備ができました。
なお、このように3回のやりとりをするので、3ウエイハンドシェイク といいます。
また、一般に相手との確認をとることを ネゴシエーション といいます。






さて、ここでもし ACK が返ってこなかったらどうなるでしょう?

TCP の動作では、データ送信後に一定時間経っても ACK を受信出来なかった場合、同じデータをもう一度送信します。

再送後に ACK を受信すれば次のデータを送る動作に移るわけですが、もしそれでも ACK を受信出来ない場合は、再送が繰り返されます。

再送が繰り返される場合は、途中の経路が混雑している場合が考えられるために、再送を行うたびに再送する時間を増やしていきます。
たとえば、最初の再送が 2 秒後、次の再送が 4 秒後、その次は 8 秒後、といった具合に増やしていき、最大で 64 秒まで増えて行きます。

そして、あらかじめ決められた回数や時間が経過しても ACK を受信出来ない場合は、TCP コネクションが切れたと判断し、
上位のアプリケーションにエラー通知を行います。





ウインドウサイズを利用したフロー制御

3ウエイハンドシェイクでコネクションを確立し、データの送信中は ACK を使用して到達確認を実施する。

これだけでも、かなりの信頼性向上になっているわけですが、TCP ではさらにもう 1 つの機能を利用して信頼性向上を図っています。

それは送信するデータ量です。

たとえば、送信側ホストがむやみにデータを送信した場合、受信側ホストのデータ処理能力が低く、
すべてのデータを受信できない可能性が発生してしまいます。

このような状態が続けば、当然通信の信頼性は落ちてしまいます。

そのため受信側ホストの処理能力を考慮しつつ、最適なデータサイズを送信する機能が必要になります。
この機能を 「フロー制御」 と呼びます。


フロー制御の動作

送信するデータのサイズは、何の情報で最適化されるのでしょうか?

それは 「ウィンドウサイズ」 を使用して最適化を行っています。
一度に受信できるデータのサイズを 「ウインドウサイズ」 と呼び、送信側ホストは受信側ホストから通知されるウインドウサイズに従って、
送信するデータのサイズを調整しています。

受信側ホストがどのようにウインドウサイズを通知するかというと、データを受信するたびに返信する ACK に
ウインドウサイズを盛り込んで通知しているのです。

もし、受信側で処理できなくなった場合は、ウインドウサイズを 「0」 にして ACK を送信します。
すると、送信側ホストはデータの送信を中断します。

受信側ホストでデータ受信が出来る状態になると、改めて ACK を送信することで、データ送信が再開されます。







(8)TCP・UDPプロトコル(トランスポート層)

TCP(Transmission Control Protocol)

TCPとは、TCP/IPプロトコル群のトランスポート層に位置するプロトコルの1つです。
トランスポート層とは、上位層から渡された情報に対して相手のどのアプリケーションに渡すべきかを認識し、その情報をデータに付加するとともに、
下位層であるネットワーク層から渡された情報についてパケットなどに欠如がないかなどをチェックします。
もしパケットに欠如などがあった場合には、再度送信を要求するなどの機能を持つものです。

トランスポート層にはTCPとUDPという機能の異なる2つのプロトコルが存在します。
トランスポート層においてTCPによってパケットの送受信を行う場合、どのアプリケーションに渡すものなのかを示す情報や、
パケットの欠如がないかなどのチェックを行うための情報をパケットに付加する必要があります。
この情報はトランスポート層を通過する際にTCPソフトウェアによって、送受信される実データの上部に付加されますが、
これをTCPセグメントフォーマット(TCPヘッダ)といいます。


TCPセグメントフォーマット

0bit                                                                  16bit                                              32bit
送信元ポート番号(Source port)
宛先ポート番号(Destination port)
シーケンス番号(Sequence Number)
確認応答番号(Acknowledgement Number)
データオフセット(Hlen)・予約(Reserved)・コードビット(Codebits)
ウインドウ(Window)
チェックサム(Checksum)
緊急ポインタ(Urgent Pointer)
オプション(Option)・パディング(Padding)

          +

データ(DATA)


図は、TCPセグメントフォーマットの内部を示したものですが、見やすいように1行32ビットで表現しています。
まず、送信元ポート番号と、宛先ポート番号です。
ポート番号は、どのアプリケーションからの情報か、どのアプリケーションヘ宛てたものかを伝えるためのものであり、
番号に応じてそれがどのようなアプリケーションであるのかはあらかじめ決まっています。

届いたパケットは宛先ポート番号を参照し、その番号に対応するアプリケーションにデータを引き渡すことになります。
ちなみに、このポート番号が21ならFTP、23ならTelnetにそれぞれデータが渡されます。
また、シーケンス番号と確認応答番号、ウィンドウなどは、パケットに欠如がないかなどを調べ、情報が正常に転送されているか否かを確認するためのものです。

確認応答番号によるシーケンス制御

TCPセグメントフォーマット内のシーケンス番号は、相手先との接続が行われた時点(コネクションの確立時)で初期化され、
その後パケットが送信されるたびに1つずつ加算されていくように前もってプロトコルとして決められています。
また、情報が正しく届いたか否かはそのつど、相手先からその旨をTCPセグメントフォーマットによって通達してくるという決まりがあります。
このことから、1つのパケットごとに応答が返ってくることになりますが(次に説明するウィンドウ制御はこの限りではありません)、
パケットを送信した際にそれが正しく届いたという応答を受けたとき、確認応答番号は、送信したシーケンス番号に1を加算した値が入れられて
返ってくることになっています。

送信側が次にシーケンス番号2を送信する際に、すでに戻ってきている確認応答番号と等しければ、直前に送ってきた情報が正しく相手に送信されていることがわかります。
このように、複数のパケットを送出する場合、そのパケットに抜けがないかをシーケンス番号と確認応答番号によってチェックすることができるわけです。

ウィンドウ制御によるパケットの連続送信

確認応答番号によるシーケンス制御では、分割されたパケットが正常に届くことを確認しながら、安全に通信を行える環境を実現していました。
しかし、パケット単位で送信と応答を繰り返すのは、安全であるものの効率はあまりよいとはいえません。
そこで、パケットをいくつかまとめて送信し、それを受信した側はまとまってすべてパケットが届いたか否かを確認し、
複数のパケットが正常に届いたなら、正常に届いた旨を応答するということが考えられました。

これによってデータの伝送効率を向上させることが可能です。
これを実現する場合には、TCPセグメントフォーマットの中のウィンドウ部を使用します。
ウィンドウには、複数のセグメントを、確認応答を待たずに送信することのできる長さをバイト数(1バイトは8ビット)で指定します。

ウィンドウで指示されるバイト数を超えない範囲であれば、複数のパケットを連続して送信することが可能となります。
もし、連続して送信したパケットに欠如などがある場合、受信側ではその旨を応答によって送信元に通達します。
するとこれを受けた送信元では、まとめて送信した分のセグメントをはじめから再び送信することになります。








ポート番号の必要性

通信において情報が伝送される場合、それがアプリケーションレベルの情報であるなら、正常に相手のアプリケーションに情報が渡る必要があります。
このためには、パケットに送信した情報に相手のコンピュータのアドレスを付加するだけでなく、届けるアプリケーション先も盛り込んでおく必要があります。
たとえば手紙を送る場合、相手の市町村と番地やマンション名を明記すればとりあえずそのマンションまでは届きます。

しかし、このマンションのどの住人に宛てたものかを明記していない場合、配達する人はどこのポストに届けていいのかがわかりません。
同様に、届けるべきコンピュータが確定していても、そのコンピュータで稼動するアプリケーションは実に多く存在するため、
アプリケーションの宛先も付加する必要があるのです。
この届けるアプリケーション先をポート番号といいます。

ポート番号は、公的に割り当てられた番号を使う場合と、動的(ダイナミック)に割り当てた番号を使う場合があります。
公的に割り当てられた番号を使う場合、ポート番号は何番がどのようなアプリケーションサービスであるかが決められているので、これに従います。

一方、動的に割り当てた番号を使う場合は、通信が行われる双方がそのつど任意に番号を割り当てて使用することになります。
なお、公的に割り当てられた番号は、みながよく知っている番号という意味合いからウェルノウンポート番号(Well-known Port Number)と呼ばれています。


UDP(user Datagram Protocol)

トランスポート層プロトコルには、TCPのほかに、もう1つのプロトコルが存在します。
このプロトコルをUDPといいます。
TCPはパケットなどに欠如がないかどうかをチェックし、もしパケットに欠如などがあった場合には再度送信を要求するものです。
これに対してUDPは、そのヘッダであるUDPセグメントフォーマットには、アプリケーション層へのデータの受け渡しのためのポート番号以外に
機能的な情報を持っていません。

すなわち、確認応答番号によるシーケンス制御や、ウィンドウ制御によるパケットの連続送信などの機能を持っていないのです。
TCPのように、シーケンス制御などを行うプロトコルをコネクション型と呼ぶのに対し、UDPのようにそれを行わないプロトコルをコネクションレス型といいます。

複数のネットワークを経由してデータが転送されるインターネットなどの場合は、途中の環境などの影響を受けやすいことから、
シーケンス制御などを行って互いにパケットが正常にやり取りできているかを随時確認する必要があります。
そこでTCPが利用されます。

一方、閉ざされたネットワークのホスト間では、より高速性を重視するためにシーケンス制御を行わない手順が使われます。
これがUDPです。

互いにやり取りの確認を行わないUDPのようなプロトコルでは、多少信頼性を落とすことになりますが、
その分高速での効率よい通信が可能となるという利点があります。
TCPとUDPのシーケンス制御については、それぞれコネクション型とコネクションレス型と呼ばれています。
このやり取りの違いは図のようになります。





コネクション型は、データ(パケット)を送信するたびに相手からの受け取り確認を待ちます。
正常に相手に届いたことが確認できたら、次のデータを送信することになります。
こうすれば正確な情報転送は実現しますが、いちいち応答確認をすると、互いの通信に関わる負担は重くなり、やり取りが遅くなります。

これに対してコネクションレス型の送信側は、相手からの応答確認を待つことなく相手にデータを送信し続けます。
相手との通信状態の確認を互いに取らないために、送信元は、データに欠如が生じているか否かを通信中確認することができない
といった問題を抱えるものの、通信の効率はよく、かつ高速で行うことが可能となります。
コネクション型とコネクションレス型は、通信環境の形態や信頼度などを考慮したうえで使い分けることになります。






Home Page