![]() |
||||||||||||||||||||||||||||||||||||||||||
![]() Linux(TCP/IP入門その1) ■03/06/21 サーバとクライアントはどんなやりとりをしているのでしょうか?「telnet」を使ったサーバとの会話以前にもっと細かく「TCP」について勉強してみたいと思います。なお、多少の言葉の表現が違っているかもしれません。 サーバとクライアントのやりとりをみてみましょう。 コネクションの確立の手順 クライアントからサーバへ接続を要求する場合、クライアントが「SYNフラグ(同期)」をたてて、シーケンス番号(ここでは例として300とします)のセグメントを送ります。セグメントとは、サーバとクライアントでやりとりにおいて、一度に送信するデータの固まりのことです。(具体的には、「トランスポート層(TCP/IPモデルでホストツーホスト層)」において、TH (TransportHeader -- TCP Header, UDP Header)を付加した状態)。 このときのシーケンス番号はそれまでやりとりされていた番号と区別させるためにランダムに割り当てられます。 次にそれを受け取ったサーバ側は、「ACKフラグ(確認)」をたて、さらにコネクションを確立できるという合図である「SYNフラグ」をたてたセグメントを送ります。また、サーバ側のシーケンス番号(ここでは例として600とします)を送るとともに、応答確認番号として先ほどクライアントから送られてきたシーケンス番号に「1」をプラスした値(ここでは301)を設定します。 クライアントは、サーバから送られてきた「SYN(シック)フラグ」+「ACK(アック)フラグ」が立ったセグメントを受信すると、確認のために「ACKフラグ」をセットしたセグメントを送ります。シーケンス番号301と応答確認番号として送られてきたシーケンス番号に「1」プラスした値(ここでは601)を設定します。 これらの確認動作でコネクションが確立したことがお互い判明したため、データを送受信する準備が整いました。
データの送受信 まず、「TCP」によるデータの送受信は、クライアントとサーバ側どちらからもデータを送ることが出来ます。また、基本的には、データを受け取った方が、「ACKフラグ」をたてたセグメントを送ります。 ここでは、クライアントのシーケンス番号を500とし、サーバ側のシーケンス番号を650とします。また、クライアント側が100バイトのデータを送った後に、200バイトのデータを送信し、その後サーバ側が300バイトのデータを送信するとします。 クライアント側が100バイトのデータとシーケンス番号(500)、応答確認番号(650)をサーバ側に送ります。 サーバ側は、受信確認として「ACKフラグ」をたて、シーケンス番号(650)と、応答確認番号として、送られてきたシーケンス番号にデータバイト数を加えた(500+100=600)値を送ります。(このためクライアント側は、どこまで送信したかがわかります) サーバから送られてきた「ACKフラグ」入りのセグメントを受け取ったクライアントは、シーケンス番号に送られてきた応答確認番号(600)をセットし、応答確認番号として、送られてきたシーケンス番号(650)をセットし、データ200バイトを送信します。 再び、サーバ側は、受信確認として「ACKフラグ」をたて、シーケンス番号(650)と応答確認番号として、送られてきたシーケンス番号にデータバイト数を加えた(600+200=800)値を送ります。 今度は、サーバ側から300バイトのデータを送信します。このときシーケンス番号は、先ほど送信したまま(650)とし、応答確認番号もそのまま(800)として送信します。 クライアント側は、受信確認として「ACKフラグ」をたて、シーケンス番号(600)と応答確認番号として送られてきたシーケンス番号にデータバイト数を加えた(650+300=900)を送ります。
コネクションの終了 データを送受信し、コネクションを終了するときは、クライアント側から「FINフラグ(終了)」をセットしたセグメントが送られます。 サーバ側は、それを受信した合図として、「ACKフラグ」をセットしたセグメントを送り返します。また、サーバ側は、「FINフラグ」をたてたセグメントを送ります。 クライアント側は、「ACKフラグ」をたてて送ります。 お互いが「FINフラグ」を受け取りその応答確認の「ACKフラグ」を受け取ると、コネクションが終了します。また、このときにどこかセグメントが消失してしまった場合は、一定時間が過ぎるとコネクションが終了します。 |
|