同じ住所の建物でも、部屋番号 (ポート番号) ごとに扉が分かれている。届いたデータは、宛先の番号の部屋のアプリに入る 住所は 1 つでも、部屋番号でアプリに届く IP アドレスは建物の住所、ポート番号は部屋番号。番号ごとに、待っているアプリが違う 住所 (IP アドレス) は この建物で 1 つ 届くデータ 443 Web サイト HTTPS 宛先 443 番 22 管理用ログイン SSH 宛先 22 番 5432 データベース PostgreSQL 宛先 5432 番 TCP の 1 つの番号で待てるのは、ふつう 1 つのアプリだけ。使用中の番号では、 待ち受けに失敗する 同じ住所の建物でも、部屋番号 (ポート番号) ごとに扉が分かれている。 届いたデータは、宛先の番号の部屋のアプリに入る
同じ住所の建物でも、部屋番号 (ポート番号) ごとに扉が分かれている。届いたデータは、宛先の番号の部屋のアプリに入る 住所は 1 つでも、 部屋番号でアプリに届く IP アドレスは建物の住所、ポート番号は部屋番号。 番号ごとに、待っているアプリが違う 住所 (IP アドレス) は この建物で 1 つ 届くデータ 443 Web サイト HTTPS 宛先 443 番 22 管理用 ログイン SSH 宛先 22 番 5432 データベース PostgreSQL 宛先 5432 番 TCP の 1 つの番号で待てるのは、 ふつう 1 つのアプリだけ。使用中の番号では、 待ち受けに失敗する 同じ住所の建物でも、 部屋番号 (ポート番号) ごとに 扉が分かれている。届いたデータは、 宛先の番号の部屋のアプリに入る
1 台のサーバーで、Web と 管理用ログインが同時に動くのはなぜか
1 台の サーバー には IP アドレス が 1 つ しかありません。それなのに、そのサーバーは Web サイトを配りながら、同時に管理用のログインも受け付けています。
IP が 1 個 しかないなら、2 つ のアプリは同時には動かせないと思うんだけど
宛先の住所が同じなら、届いたデータはどちらのアプリのものなのでしょうか。この行き先を決めているのがポート番号です。
住所と、部屋番号
IP アドレス が建物の住所だとすれば、ポート番号は部屋番号です。住所だけでは建物までしか届きません。部屋番号があって初めて、中の誰宛かが決まります。
ポート番号は 16 ビットの数値で、0 から 65535 までを取ります。サーバー側のアプリは起動時に「私は何番で待ちます」 と宣言し、そこへ来たデータだけを受け取ります。 HTTPS は 443 番 、SSH は 22 番 、PostgreSQL は 5432 番 、というふうに、よく使われるものには慣例の番号が決まっています。慣例なので技術的には変えられますが、変えると相手が探せなくなるので、公開するものは慣例に従います。
番号の範囲は、おおまかに 3 つ に分かれています。
0 から 1023 は 、標準的なサービス用に予約されている範囲です。ここで待ち受けるには管理者権限が要ります
1024 から 49151 は 、登録済みだが必須ではない範囲です。開発中に 3000 番 や 8080 番 を使うのはここです
49152 以降は、その場限りの用途に空けてある範囲です
番号を指定せずに通信することはできません。 ブラウザ に https://example.com と打ったとき番号が見えないのは、省略しているだけで、種類に応じた慣例の番号が自動で補われているからです。慣例と違う番号で動かしている サーバー に繋ぐときだけ、末尾に番号を書く必要が出てきます。
頼む側の番号は、毎回変わる
待ち受けの 443 番は 1 つでも、接続は相手の IP と番号の組で分かれる。組が違えば、同じ扉に同時にいくつも繋がる 443 番の扉 1 つに、同時にいくつも繋がる 3 本の接続が、どれも同じ 443 番の扉を通る。サーバーは相手の IP と番号の組で見分ける 443 頼む側 (3 本の接続) サーバー (IP は 1 つ) 受けている接続 相手の IP 相手の番号 相手 A A 49152 相手 B B 49152 相手 A (2 本目) A 49153 待ち受けは 443 番の扉 1 つ IP と番号の組が 1 つでも違えば、別の接続として見分ける 3 本の見分け方 比べる 2 本 違う所 1 本目と 2 本目 相手の IP (A と B)。番号は同じ 49152 1 本目と 3 本目 相手の番号 (49152 と 49153)。IP は同じ A 頼む側の番号は、OS が接続のたびに空いているものを割り当てる 待ち受けの 443 番は 1 つでも、接続は相手の IP と番号の組で分かれる。組が違えば、 同じ扉に同時にいくつも繋がる
待ち受けの 443 番は 1 つでも、接続は相手の IP と番号の組で分かれる。組が違えば、同じ扉に同時にいくつも繋がる 443 番の扉 1 つに、 同時にいくつも繋がる 3 本の接続が、どれも同じ 443 番の扉を通る。 サーバーは相手の IP と番号の組で見分ける 443 頼む側 (3 本の接続) サーバー (IP は 1 つ) 受けている接続 相手の IP 相手の番号 相手 A A 49152 相手 B B 49152 相手 A (2 本目) A 49153 待ち受けは 443 番の扉 1 つ IP と番号の組が 1 つでも違えば、 別の接続として見分ける 3 本の見分け方 比べる 2 本 違う所 1 本目と 2 本目 相手の IP (A と B)。 番号は同じ 49152 1 本目と 3 本目 相手の番号 (49152 と 49153)。 IP は同じ A 頼む側の番号は、OS が 接続のたびに空いているものを割り当てる 待ち受けの 443 番は 1 つでも、 接続は相手の IP と番号の組で分かれる。 組が違えば、同じ扉に同時にいくつも繋がる
見落としやすいのが、頼む側にも番号が要るという点です。応答をどの部屋に返すかを決めないといけないからです。
この番号は OS がその都度、空いているものを自動で割り当て、使い終われば回収します。ふだん意識する必要はありません。ただし、同じ相手へ短い接続を大量に張り続けると、割り当てる番号が尽きて接続に失敗することがあります。バッチ処理で「しばらく動いてから急に接続できなくなる」という症状の定番の原因です。接続を毎回捨てずに使い回す、という対策が効きます。
番号が尽きるって言うけど、65535 もあるのに尽きたりするものなの?
ふむ、実際に尽きる。同じ相手へ短い接続を大量に張り続けると、割り当てる番号が使い切られて失敗する。
待ち受ける側にも決まりがあります。1 つ のアプリが複数の番号で待つことはできます。一方、同じ通信方式で同じ IP の 同じ番号は、ふつう 2 つ 目のアプリが待ち受けに失敗します。すでに使われている番号で起動しようとすると、その場でエラーになって立ち上がりません。前回の開発サーバーが終了しきっておらず、次を起動できない、という詰まり方がこれです。
なお、番号の空間は TCP と UDP で 完全に別です。TCP の 5432 番 と UDP の 5432 番 は、無関係な別の部屋です。関所の設定を書くときに、どちらのことなのかを必ず明示しなければならないのはこのためです。片方だけ開けて「番号は開けたのに繋がらない」と悩むのは、誰もが一度は通る道です。設定画面で TCP と UDP のどちらが選ばれているかを、まず見てください。
つまり、TCP の 5432 番 と UDP の 5432 番 は、見た目は同じでも別物ってことか
うむ、その通り。ただし、両方とも開けるべきかどうかまでは、使うアプリ次第でここでは決めていない。