TCP/IP とは
TCP/IP とは、レイヤー 3 の IP とレイヤー 4 の TCP/UDP を組み合わせて通信を行う取り決め (プロトコル) のことで、現在のインターネット通信の一般的な通信モデルです。
更に上位レイヤー (http, dns, ftp, ntp 等) のプロトコルは一般に、この TCP/IP 通信にカプセル化されて相手先に情報が送られます。
また、更に下位レイヤー (物理ケーブル/Ethernet 等) は、伝送メディアによって変わりますが、この TCP/IP 通信をカプセル化します。
TCP/UDP とは
TCP と UDP はともにクライアントとサーバ間での通信チャネルの提供、通信管理を行う、レイヤー 4 のプロトコルです。
通信チャネルというのはいわゆる "ポート" というもので、1 番から 65535 番までの番号が使用できます。同じ IP アドレスであっても TCP や UDP のポートが異なれば、提供されるサービスが異なります。
早い話が、TCP や UDP を使うことで、ある 1 台のサーバの 1 つの IP アドレスで、複数のサービス (http/dns/SMTP 等) を提供できるようになります。
1 つのサービスについて、TCP しか使えないもの、UDP しか使えないものもありますが、TCP と UDP 両方使えるものもあります。たとえば DNS は両方利用可能です。
サーバのポート番号
例えば、192.168.1.1 の IP を持つサーバにおいて、HTTP サービス (Apache/TCP port 80 )と DNS サービス( Bind/UDP port 53 )、SMTP サービス (Postfix/TCP port 25) が動作させることができます。
クライアントから 192.168.1.1 の TCP:80 番ポートへ接続すれば、HTTP サービスが提供されます。
クライアントから 192.168.1.1 の UDP:53 番ポートへ接続すれば、DNS サービスが提供されます。
クライアントから 192.168.1.1 の TCP:25 番ポートへ接続すれば、SMTP サービスが提供されます。
このとき、(サーバ側ではな) クライアント側のポート番号が何番かというのはあまり意味がありませんが、例えば同一クライアントから HTTP サービスへ 2 つの TCP コネクションを張りにいくこともありますので、サーバ側で、同一クライアントの 2 つの通信を識別するのに役に立ちます。
なお、HTTP は TCP:80 番ポート、DNS は UDP:53 番ポート、SMTP は TCP:25 番ポート、というのは Well-Known-Port (ウェルノウンポート) と呼ばれ、一般的に使われるポート番号です。この割り当ては IANA が行なっており、 IANA のページに公開されています。ただし、この決め事は絶対ではありません。
例えば下図のように、HTTP は 234 番でもいいですし、DNS は UDP じゃなく TCP でもよく、さらに 53 番じゃなく 106 番にしても構いません。
これは Web サーバや DNS サーバ、メールサーバの設定で変更可能ですし、アプリケーション開発者が自由に決めても構いません。
TCP を使った http 通信については以下の記事もご参照下さい。3 way handshake から http 通信をするところをパケットキャプチャを載せて紹介しています。TCP と http の違いがはっきり理解できるかと思います。
クライアントのポート番号の範囲
クライアントのポート番号は基本的には higher port と呼ばれる、番号の後ろのものが使われます。
Windows については、Vista 以降は IANA の勧告に従い、Ephemeral Port (49152~65535) が使われます。設定はコマンドプロンプトの以下コマンドで確認できます。(49152+16384-1 = 65535 であることに注意)
C:\>netsh interface ipv4 show dynamicport tcp
プロトコル tcp の動的ポートの範囲
---------------------------------
開始ポート : 49152
ポート数 : 16384
C:\>netsh interface ipv4 show dynamicport udp
プロトコル udp の動的ポートの範囲
---------------------------------
開始ポート : 49152
ポート数 : 16384
Linux については 32768~60999 が使われています。これはカーネルパラメータに定義されており、sysctl -a で確認できます。
# sysctl -a ~~~ net.ipv4.ip_local_port_range = 32768 60999 ~~~
TCP と UDP の使い分け
TCP は特に、高信頼性 (3 way ハンドシェイクによる通信前の打診、ack による相手の受信確認や再送処理、等) や 通信効率の最適化機能 (Window によるフロー制御や輻輳制御) を提供します。そのため、UDP と比べて負荷がかかります。
一方、UDP は送信相手に通信チャネルとチェックサムを提供するのみのシンプルな構成のため、負荷が軽いですが、信頼性や通信の効率性を提供する機能はありません。通信も一方的です。
TCP は、Web 通信、メール通信、ファイル転送などの、信頼性を求められる通信に向いています。TCP は片方向ずつコネクションを確立します。つまり、TCP syn ではクライアントからサーバへのコネクションの開始の打診、TCP syn/ack では syn に対する承認と、サーバからクライアントへのコネクションの開始の打診、TCP ack では直前の syn に対する承認を行います。
一方、UDP は音声や動画などのリアルタイムアプリケーションや、syslog や DNS, NTP, SNMP, TFTP などの簡易なプロトコルに向いています。
UDP は syslog のように 1 方向のものもあれば、DNS や NTP のように双方向のものもあります。
なお、この使われ方については時代変化が激しく、昔は動画は UDP が常識でしたが高速化や Web ベースでの動画視聴が主流になると TCP での配信が増えました。しかしここ最近は『TCP では高速化に導けない』として UDP 上に QUIC というプロトコルを乗せ、QUIC 上でHTTP プロトコルを使う時代に入りました。このあたりの詳細は以下の HTTP/3 のページも併せてご参照下さい。
ちなみに完全な余談ですが、若手の頃、ある人が『TCP は恋人のメール (LINE) の仕方、UDP は夫婦のメール (LINE) の仕方、と覚えろ』と言っていたのを今、しみじみと感じています。つまり、、、
TCP (恋人のメールの仕方) の場合
---7/23(月)---
0:11 A子『ねえ、まだ起きてる?』(syn)
0:11 B男『ん?起きてるよー』(syn/ack)
0:12 A子『よかった!まだ起きてるんだ!今日さー、〜〜〜』(ack、通信開始)
UDP (夫婦のメールの仕方)の場合
---7/23(月)---
17:45 B男『これから帰ります』
---7/24(火)---
19:23 B男『これから帰ります』
---7/25(水)---
17:35 B男『これから帰ります』
17:45 A子『卵買ってきて』
---7/26(木)---
20:56 B男『これから帰ります』
ソケット
TCP では、『クライアントのアプリケーション』と『サーバのアプリケーション』間での データのやり取り (通信) を規定しています。
下図は、クライアントの InternetExplorer (クライアントのアプリケーション)がサーバの Apache (サーバのアプリケーション)にTCPでデータのやり取りをする イメージ図です。(Apache は代表的な Web サーバソフトウェアです。)
『192.168.1.1:50001 ⇔ 10.0.0.1:80』というような、送信元IPアドレス:送信ポート、 宛先IPアドレス:宛先ポートの組合せのことをソケット (socket)と呼びます。
クライアントのアプリケーション (ブラウザ) もサーバのアプリケーション (Apache) も、このソケットという単位で通信を管理しています。そのため、クライアントのポート番号さえ異なれば、1 つのクライアントで同時に同じサーバポートにアクセスすることもできます。
通信をこのように管理するゆえ、【TCP/IP】という言葉があるのです。(UDP/IP とはあまり言わないですが、TCP/IP 通信と呼ぶものの中には UDP も含めていることが多いです。)
アプリケーションはこのソケットを識別子として仮想回線を張り、TCP コネクションを確立します。このとき、IP のルーティング経路は、行きと帰りで違っていても問題ありません。RIP や OSPF 等の動的ルーティングプロトコル等で途中で経路が変わっても、このコネクションが切れることはありません。
なぜなら、レイヤー 3 以下で動作する NW 機器では TCP コネクションは認識しておらず、クライアント/サーバのホスト間だけで認識しているためです。
ただし、ファイアウォール等のレイヤー 4 以上の NW 機器では TCP コネクションや UDP の往復を管理する機能(ステートフル・インスペクション)があるので、経路の途中にファイアウォールがある場合は行きと帰りを同じ経路で往復させる必要があります。
余談ですが、ソケットはアプリケーション開発においても、ソケット API という API が提供されています (Windows のソケット API は特に Winsock と呼びます)。
プログラマはプログラム上で通信が必要な場合はこのソケット API を呼び出すだけでよいので、通信に関するプログラムを書く必要がなくなります。
さらに余談ですが、Winsock は OS のバージョンによって段々と変わってきています。特に大きな変化としては、Windows XP SP2 以降で、RAW ソケットを禁止したことです。
通常のソケットはデータ送信をする際に TCP/UDP のヘッダは自動で生成、出力されますが、RAW ソケットを使うと、Ethernet ヘッダ、IP ヘッダも含め、全て利用者が手動で生成できます。これが結局悪いことばかりに使われたため、セキュリティのために MS が禁止にした、というのが実情のようです。
nesukeの推薦図書
以下に該当する人なら熟読することを強く推奨します。
- 周りのネットワークエンジニアよりも一歩抜き出た存在となり、価値を高めたい!
- サーバエンジニアだけどネットワークも含めた総合的なセキュリティへの理解も深めていきたい!
コメント
管理人様
とても素晴らしい内容でわかりやすかったです。
私も自己研鑽のためにブログを始め、勉強記録をつけているのですが、
貴サイトに記載してある内容は今後も活用していきたく存じます。
可否含めて可能な範囲のご確認をさせていただければと存じますので、
一度お話させていただくこと可能でしょうか。
もし可能であれば記載いたしましたメールアドレスにお返事いただければと存じます。
以上、よろしくお願いいたします。
koike90s