「URLを検索して、結果が画面に表示されるまで」って意外と説明できない
この記事は「はじめてのアドベントカレンダー」11日目の記事です。
最近の気付き
エンジニアになって早くも九ヶ月が経ったのですが、タイトルにあるように
「URLを検索して、結果が画面に表示されるまで」という極々シンプルな動作でも
「サーバー」とか「ポート」とか「IPアドレス」とか「DNS」とか
基本的な用語を理解していないといけなくて、
意外と分かってるようで分かってないなあ〜と感じたので、この機会に振り返ることにしました。
あくまで自分の言葉で、直感的に分かりやすいようにアウトプットすることを目的にしているので、正確ではないところもあると思います。ご了承ください。
普通に難しい
「https://google.com と検索したら、Googleの検索画面が表示されます。」
という裏側で何が起きているのかというと、
「クライアントからリクエストが送信されると、まずDNSによってリクエスト先のドメイン名がIPアドレスに変換されます。そのIPアドレスを持つサーバーがリクエストを受け取ると、リクエストに含まれるポート番号に基づき、そのポートを待ち受けている特定のアプリケーションにリクエストが渡されます。アプリケーションはリクエストを処理してレスポンスを生成し、クライアントへと返却します。」
...そんなこと言われても、むずかしい、眠くなる!
改めて整理してみる
例えば、ブラウザ(=PCやスマホの画面)からhttps://example.comと検索して、検索結果が画面に表示されることを考えてみます。
https://example.comと入力して「検索」をクリックしたとき、裏側では何が起きているでしょうか?
1. https://example.comが意味するもの
何気なく使っているURLですが、URLは「スキーム」「ホスト」「パス」の大きく3つから構成されています。
https://example.com/index
----- ----------- -----
スキーム ホスト パス
URLの「ホスト」部分には、大抵の場合「ドメイン名」が入ります。google.comとかqiita.comみたいなやつです。
この「ドメイン名」は「google.comというコンピューターに接続してね」ということを表していて、いわば住所のようなものです。
でも、ドメイン名はあくまで人間が分かりやすいように付けられたもので、コンピューターの理解できる表現ではありません。そこで、「ドメイン名」はコンピューターでも理解できるように「IPアドレス」に変換されます。
「ドメイン名」=「花子さんの家」
「IPアドレス」=「〒330-0841 埼玉県(今はなき)大宮市oo町x丁目y番o号」
みたいなものです。

2. DNSサーバーでIPアドレスとドメイン名を紐づける
ここで、ドメイン名をIPアドレスに変換してくれるのが「DNSサーバー」です。
「DNSサーバー」は住所台帳のようなもので、どのドメイン名とIPアドレスが紐づいているかを知っています。
https://example.comと入力して「検索」をクリックすると、クライアント(ブラウザ)からDNSサーバーに「example.comに対応するIPアドレスを教えて〜」とリクエストが行きます。リクエストというのは、ブラウザからDNSサーバーに質問がいく、ってことです。
すると物知りなDNSサーバーさんは「example.comに対応するIPアドレスは192.168.100.100ですよ」と親切に教えてくれます(※1)。

答えを教えてもらったクライアントは「192.168.100.100という住所のサーバーに行けばhttps://example.comを開けるんだ!」と理解します。
(※1) DNSサーバーは一人で頑張っているわけではなく、複数で協力して頑張っています。
「キャッシュDNSサーバー」とか「権威DNSサーバー」で調べてみてください。
3. 目的のポート番号へ向かう
無事192.168.100.100という住所のサーバーに到着しました。
そこにはたくさんの部屋番号(=ポート)が並んでいます。
さて、https://example.comとアクセスしたら、どの部屋番号に向かうのでしょうか。
ここで着目するのが、さっき書いたURLのスキーマの部分です。
実は、httpsというのは443番ポートにデフォルトで割り当てられています。(※2)
なので192.168.100.100という場所にあるサーバーの443番のお部屋に向かいます。

こうして無事リクエストが到達し、443番の部屋で立ち上がっているアプリがリクエストを処理してくれます。
(※2) 0から1023番のポートは、Well-known portsと呼ばれ、よく使われるアプリやサービスに割り当てられています。例えば80 -- http、443 -- httpsといった具合です。(Well-known ports 一覧)
4. サーバーからクライアントへレスポンスが返る
アプリでリクエストが処理されると、レスポンスが生成されます。
手紙に書かれたお願い(リクエスト)を読んだら、
頭の中で「どーしよっかなー」と考えて(処理して)、
返事を書く(レスポンスを生成する)
ようなものです。
で、このレスポンスというお返事を返さなくてはいけないので、サーバーがクライアントにレスポンスを返却します。
クライアントはレスポンスを「ふむふむ」と確認して、その内容を画面上に表示したりします。
こうして、晴れてブラウザ上に検索結果が表示されます!
まとめ
今回この記事を書くために、書籍「プロになるためのWeb技術入門」を改めて読み返したのですが、入社当初に読んだ時よりも格段に理解できることが増えていたのが、ちょっぴり嬉しかったりしました。
まだまだできないこともたくさんありますが、こうして自分の成長を感じられるのは良いものですね。
おまけ: Wiresharkでリクエストやレスポンスを可視化する
ネットワーク上で行われているリクエストやレスポンスって可視化できないのかなあと思っていたら、Wiresharkというパケット(= リクエストやレスポンスで運ばれる情報を小分けにして入れる小さな箱)を可視化してくれるツールがあることを知りました。
試しに、阿部寛のHP (http://abehiroshi.la.coocan.jp/) (※3)にアクセスすると、下のような感じでログが表示されます。(適宜マスキングしています)
No. Time Source Destination Protocol Length Info
.
.
.
(略)
.
.
.
215 7.635764 192.168.1.100 8.8.8.8 DNS 83 Standard query 0xeb74 HTTPS abehiroshi.la.coocan.jp
216 7.636112 192.168.1.100 8.8.8.8 DNS 83 Standard query 0x53b5 A abehiroshi.la.coocan.jp
217 7.649720 8.8.8.8 192.168.1.100 DNS 99 Standard query response 0x53b5 A abehiroshi.la.coocan.jp A 222.158.205.72
218 7.653392 8.8.8.8 192.168.1.100 DNS 170 Standard query response 0xeb74 HTTPS abehiroshi.la.coocan.jp SOA ns-1752.awsdns-27.co.uk
219 7.655551 192.168.1.100 222.158.205.72 TCP 78 63935 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=241762168 TSecr=0 SACK_PERM
220 7.666231 222.158.205.72 192.168.1.100 TCP 74 80 → 63935 [SYN, ACK] Seq=0 Ack=1 Win=14600 Len=0 MSS=1460 WS=1 SACK_PERM TSval=103591658 TSecr=241762168
221 7.666410 192.168.1.100 222.158.205.72 TCP 66 63935 → 80 [ACK] Seq=1 Ack=1 Win=3146560 Len=0 TSval=241762179 TSecr=103591658
222 7.666469 192.168.1.100 222.158.205.72 HTTP 498 GET / HTTP/1.1
223 7.685027 222.158.205.72 192.168.1.100 TCP 66 80 → 63935 [ACK] Seq=1 Ack=433 Win=15032 Len=0 TSval=103591677 TSecr=241762179
224 7.689464 222.158.205.72 192.168.1.100 HTTP 841 HTTP/1.1 200 OK (text/html)
.
.
.
(略)
.
.
.
関連するログを見ていくと、
215 7.635764 192.168.1.100 8.8.8.8 DNS 83 Standard query 0xeb74 HTTPS abehiroshi.la.coocan.jp
ここで、ブラウザからDNSサーバーへ「阿部寛のHPを開いて」というリクエストを送信しています。(※4)
192.168.1.100がクライアント(ブラウザ)のIPアドレス、8.8.8.8がGoogle Public DNS(※5)のDNSサーバーのIPアドレスです。
216 7.636112 192.168.1.100 8.8.8.8 DNS 83 Standard query 0x53b5 A abehiroshi.la.coocan.jp
同時に、ブラウザからDNSサーバーへドメイン名abehiroshi.la.coocan.jpに対応するIPアドレスを問い合わせています
217 7.649720 8.8.8.8 192.168.1.100 DNS 99 Standard query response 0x53b5 A abehiroshi.la.coocan.jp A 222.158.205.72
DNSサーバーに問い合わせた結果、abehiroshi.la.coocan.jpに対応するIPアドレスは222.158.205.72であることが判明しました
219 7.655551 192.168.1.100 222.158.205.72 TCP 78 63935 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=241762168 TSecr=0 SACK_PERM
ここで、クライアント(ブラウザ、192.168.1.100)からサーバー(222.158.205.72)への接続がリクエストされています。阿部寛のHPのURLはhttp://...で始まるので、ポートは80番になっていることもわかります。
220 7.666231 222.158.205.72 192.168.1.100 TCP 74 80 → 63935 [SYN, ACK] Seq=0 Ack=1 Win=14600 Len=0 MSS=1460 WS=1 SACK_PERM TSval=103591658 TSecr=241762168
221 7.666410 192.168.1.100 222.158.205.72 TCP 66 63935 → 80 [ACK] Seq=1 Ack=1 Win=3146560 Len=0 TSval=241762179 TSecr=103591658
サーバーはリクエストを許可し、TCP接続が開始されることを表しています。(※6)
222 7.666469 192.168.1.100 222.158.205.72 HTTP 498 GET / HTTP/1.1
TCP接続が確立されたので、クライアントは「阿部寛のHPを表示してください」というHTTPリクエストGET / HTTP/1.1をサーバーに送信します。
223 7.685027 222.158.205.72 192.168.1.100 TCP 66 80 → 63935 [ACK] Seq=1 Ack=433 Win=15032 Len=0 TSval=103591677 TSecr=241762179
224 7.689464 222.158.205.72 192.168.1.100 HTTP 841 HTTP/1.1 200 OK (text/html)
サーバーはHTTPリクエストを受け付け、ステータスコードHTTP/1.1 200 OKとともに、要求されたHPの中身を送信します。
以降ではページ表示に必要な情報が順次サーバーに要求され、画面に表示されます。
#リクエストの送信(GET /menu.htm, GET /top.htm)
226 7.696958 192.168.1.100 222.158.205.72 HTTP 548 GET /menu.htm HTTP/1.1
231 7.716254 192.168.1.100 222.158.205.72 HTTP 547 GET /top.htm HTTP/1.1
#レスポンス(text/html)
234 7.718786 222.158.205.72 192.168.1.100 HTTP 1408 HTTP/1.1 200 OK (text/html)
241 7.736268 222.158.205.72 192.168.1.100 HTTP 629 HTTP/1.1 200 OK (text/html)
#画像データのリクエスト送信(GET /abe-top-20190328-2.jpg, GET /image/abehiroshi.jpg)
244 7.738173 192.168.1.100 222.158.205.72 HTTP 468 GET /abe-top-20190328-2.jpg HTTP/1.1
245 7.738344 192.168.1.100 222.158.205.72 HTTP 466 GET /image/abehiroshi.jpg HTTP/1.1
#画像データをレスポンスとして返す(JPEG JFIF image)
251 7.760204 222.158.205.72 192.168.1.100 HTTP 513 HTTP/1.1 200 OK (JPEG JFIF image)
(※3) もうすぐhttpはなくなり、httpsに一本化されるらしいです泣
(※4) ちなみに、このログにあるHTTPSは、HTTPのことではなくDNSのレコード種別の一つのようです
(※5) Googleが提供している、誰でも使える無料のDNSサーバーです
(※6) TCPはデータの抜けや化けがないように通信するための仕組みです。(勉強中です汗)
Discussion