Webサイトが表示されるまで
今回はWebサイトが表示されるまでに行われることやネットワークの基礎中の基礎をまとめたいと思います
URLについて
皆さんは、URLを入力してWebサイトに接続すると思います
URLにはアクセスしたいファイルやドメインの情報が含まれていてブラウザはURLを解析して目的のファイルを取得します
例えば、このブログのURLであるhttps://kumaskun.hatenablog.com/entry/2023/01/08/123900
を例にみていきましょう!
プロトコル・スキーム
まずはhttps://
の部分です。
httpsの部分はプロトコル
と呼ばれています。
URLは通信をするときに使うので、「通信プロトコル」とも呼びます
プロトコルはインターネット上で通信をするとき、このルールに従いましょうという取り決めのことを指します。 中でも、通信プロトコルには、次のように目的に応じて様々な種類があります
よく使うのはhttp
とhttps
だと思います
httpとは、Hyper Text Transfer Protocol
の略で、WebサーバーとWebブラウザがデータを送受信するときに使う通信上のルールのことです。
例えば、Google ChromeのWebブラウザからhttpという通信プロトコルを使ってWebサーバーに要求を出すことで、そのページを表示させて利用できるようになります。
httpsはHyper Text Transfer Protocol Secure
の略で、httpにデータを暗号化する機能がついたものです。
Secure Socket Layer、transport layer securityはそれぞれSSL
とTLS
と省略し、どちらもデータを暗号化して送受信する技術のことを指します。
SSLとTLSの技術でデータを暗号化することにより、個人情報などの漏洩を防ぎます。
現在のURLの形式はhttpsがほとんど占めると思います
https://
はまとめてスキームと呼ばれています。
前述したプロトコルというルールを規定するものだと理解しましょう。
上図の場合では、このURLはhttpsのルールを使って通信することを表しています
ドメイン
次はドメインについてです。ドメインはkumaskun.hatenablog.com
の部分です
ドメインは、ホスト名と同じく、IPアドレスを分かりやすくするために設定する文字列のことを指します。 インターネット上の住所となるので、同じドメインは1つしか存在しません。Webサイトを作成する際にはまず、ドメインの取得から行うことが多いと思います
ドメインには、更に細かくトップレベルドメイン
、セカンドレベルドメイン
、サードレベルドメイン
の3つに分けられます。
トップレベルドメインは、ドメインの一番最後にあるjp
、com
、net
などです。
特定の領域や分野ごとに割り当てられた分野別トップレベルドメイン(gTLD)と、国別のコードに割り当てられたトップレベルドメイン(ccTLD)に大別されます。
例えば、日本のccTLDは上図の「jp」です。
セカンドレベルドメインは、ドメインの中で2番目に属しているドメインです。(今回はhatenablogの部分) この階層はあくまで順番を表しているため、トップレベルドメインの種類によって、どのようなドメインがセカンドレベルドメインになるかは変わります。
トップレベルドメインがjpの場合は、co(組織)
やor(非営利法人)
など、組織の種類を表すドメインが入ります。
一方、トップレベルドメインが下図のようにcomやnetなどの場合は、サードレベルドメインがセカンドレベルドメインの位置に入るため、サードレベルドメインがないURLもあります
サードレベルドメインは、セカンドレベルドメイン以下に属しているドメインです。 上図の場合、このサードレベルドメインのkumaskunは、重複がない限り登録者が自由に設定できます
IPアドレスとは?
補足情報としてIPアドレスについて軽く触れておこうと思います
IPアドレスは、スマホやPCなど、ネットワーク上の機器に割り当てられるインターネット上の住所のようなものです。 インターネットでページを閲覧したり、メールの送受信を行うには、データの送信元や送信先を識別する必要があります。 そこで、この識別に使うための番号がIPアドレスです。 ネットワーク上でデータを送受信する際、通信相手を指定するために使われています
IPアドレスはネットワーク番号
とホスト番号
から構成されています。
どのサブネット(ハブにコンピューターを接続したもの)に属しているかを示す番号をネットワーク番号、
サブネット内のどのコンピューターからを表す番号をホスト番号と呼びます
IPアドレス32bitのデータで8bitずつドットで区切り10進数で表記します。
例えば、100.12.11.100
のようなイメージです
しかし、100.12.11.100だけだとどこまでがネットワーク番号でどこまでがホスト番号がわかりません。
そこで、100.12.11.100/16
と書くことで最初の16bitがネットワーク番号になり、残りの16bitがホスト番号とわかるようになります
ホスト名
今回の例のURLにはないのですが、URLにはホスト名というものが存在します
例えば、www
などの文字を1度は見たことがあるのではないでしょうか?
ホスト名は、ネットワークに接続されたホスト(機器やサーバー)の名前を指します。 通信する際に、特定のホストを識別するために使います
ホスト名は、後述するドメインとほとんど同じ意味だと捉えて構いません。 人間が管理しやすいように、前述したIPアドレスを文字に置き換えているの文字列が「ホスト名」と「ドメイン」です。
ホスト名もドメインも、どちらも登録者の任意で自由に決めることができます。 ホスト名は、代表的な「www」にするか、自由に設定するか、必要がなければ省略することもできます
ディレクトリ
ディレクトリは、サーバー内のフォルダ名と位置を表しています。 ホームページの場合、複数のコンテンツを持っていることがほとんどです。 そのコンテンツを分類し、このURLがホームページ内のどの階層にあるページなのかを示しています。
ディレクトリが何層もある場合は、URLの中では一番左の、一番大きなディレクトリより後のものをサブディレクトリといい、「/」で区切ります。
今回の例の場合には2023
がディレクトリにあたり、/01/08/
はサブディレクトリに相当します
ファイル名
ファイル名は、URLの末尾に配置される一番小さなファイルを表します。
そのURLの中では一番最後の部分です。今回は123900
の部分です。
今回の例では、ディレクトリの中の123900に分類されたファイルを開くようなURL構成になっています
リクエストメッセージ
ここまでで、HTTPプロトコルやHTTPSプロトコルを使ってどのドメインやどのファイルにリクエストするかがURLを見ればわかるようになったと思います
次にブラウザはサーバーに対してデータをリクエストする旨を伝えるリクエストメッセージを作成します。 リクエストメッセージはHTTPプロトコルに準拠している必要があります
ここからはリクエストメッセージの構成に関して説明します。まずは下記にリクエストとレスポンスのイメージ画像を載せます
メソッド
メソッドはWebサーバーにどのような処理をして欲しいのかを記述します。今回の例ではPOST
が該当します。
他にはGET
やPUT
などがあります。
例えばGETはリソースを取り込むこと、POSTはデータをサーバーへ送信すること (リソースを作成または変更する、あるいは返送する一時的なドキュメントを生成する) ことを示します
HTTPバージョン
どのバージョンのHTTPプロトコルに準拠しているかを定義しています。今回の場合にはHTTP/1.1
でバージョン指定を行っています
メッセージヘッダー
メッセージヘッダーはリクエストに対して付加情報を記述したい場合には追加します。上記の図ではHTTP Headersと命名されている箇所です
使用できるリクエストヘッダーは多数あり、いくつかのグループに分類されます
- 一般ヘッダーは: Via など、メッセージ全体に適用される
- リクエストヘッダー:
User-Agent
,Accept-Type
など指定するとリクエストを変更するもの (Accept-Language
など)、状況を示すもの (Referer
など) - エンティティヘッダー:
Content-Length
など、リクエストの本文に適用されます。リクエスト内に本文がない場合はこれらのヘッダーが送信されません
メッセージボディー
リクエストの最後の部分が本文です。 本文が存在しないリクエストもあります。 リソースを取り込むリクエストであるGET, HEAD, DELETE, OPTIONSは通常、本文は不要です。 サーバー内のデータを更新するためにデータを送信するリクエストもあり、 POST リクエストでよくあります (HTML フォームのデータを持つ)
本文は、大きく 2 種類に分類されます。
- 単一リソースの本文。1 個のファイルで構成され、Content-TypeとContent-Lengthの 2 つのヘッダーで定義される
- 複数リソースの本文。マルチパートの本文で構成され、それぞれが異なる情報を持ちます。これは主に、 HTML フォームと関連付けられる
レスポンスメッセージ
レスポンスメッセージはHTTPリクエストに対するレスポンスです。 少し細かくいうと、ホームページを見るときに使うソフト(Webブラウザ)からホームページのファイルが置いてあるコンピュータ(Webサーバ)に対して出されるリクエストに対するWebサーバさんからの返事です
レスポンスメッセージはリクエストメッセージで表示させているイメージをベースに説明します
ステータスコード
ステータスコードHTTPリクエストが正常に処理されたかを示す数字です
大まかに5種類に分けられます
- 情報レスポンス:ステータスコードは100~199。Webサーバーにリクエストを行ったときの情報が不足したり時間がかかりすぎた場合に返却されるステータスコード
- 成功レスポンス:ステータスコードは200~299。リクエスト成功して正常にレスポンスを返却さいた場合に返却されるコード
- リダイレクト:ステータスコードは300~399。リダイレクトを行ったときに返却されるステータスコード
- クライエントエラー:ステータスコードは400~499。データが存在しない場合やデータを見る権限がないなどのリクエストに問題ある時に返却されるステータスコード
- サーバーエラー:ステータスコードは500~599。サーバーに問題あり正常にリクエストが実行されていない場合に返却するステータスコード
レスポンスメッセージ
レスポンスの最後の部分が本文です。 本文を持たないレスポンスもあります。
本文は、大きく 3 種類に分類されます。
- 大きさが判明している 1 個のファイルで構成される、単一リソースの本文。 Content-Type と Content-Length の 2 つのヘッダーで定義される
- 大きさが不明な 1 個のファイルで構成される、単一リソースの本文。
Transfer-Encoding
をchunkedに設定して、 chunked 形式でエンコードされる - 複数リソースの本文。マルチパートの本文で構成され、それぞれが異なる情報のセクションを持ちます。これは比較的まれ
DNS
ここまででサーバーにリクエストを行い、レスポンスが返却されるという流れは把握したと思います
リクエスト時にデータを送信するためには宛先のIPアドレスを知る必要があります
URLから得られる情報はドメイン名(IPアドレスを人間が理解しやすくしたもの)なので、IPアドレスに変換する必要があります。そこでDNSという仕組みがあります
DNSはIPアドレスとドメイン名を対応づけします。
例えば、https://kumaskun.hatenablog.com/
のIPアドレスを問い合わせるとDNSサーバーが100.100.100.100
のようにIPアドレスを教えてくれます。
DNSサーバーを使用してIPアドレスを取得するのを名前解決
と呼びます
DNSサーバーとresolver
ドメイン名の情報を管理し、外部からの問い合わせに応答するコンピュータやソフトウェアのことをDNS server
、サーバへの問い合わせを行いDNS情報を参照・利用する側のコンピュータやソフトウェアをDNS client
あるいはDNS resolver
という。
DNS resolverはIPアドレスを問い合わせる側のことです
resolverには以下3つの情報が含まれています。これらの情報をリソースレコード
とも呼びます
- 名前:サーバーやメールの@以降の情報
- クラス:DNSがどのような目的で使用されているかがわかる
- タイプ:AタイプとMXタイプがある。Aタイプは名前とIPアドレスが対応づけされている場合でMXタイプは名前とメールサーバーが対応づけされている場合
DNSサーバーは複数存在しています。インターネット上には数枚台というDNSサーバーがありそれぞれ自分が担当するドメインを持っています
実際に問い合わせを行う場合には、ツリー構造でつながれているネットワーク上に配置されたほかのDNSサーバーに対して、問い合わせを受けたDNSサーバーが問い合わせをします。
この問い合わせをするプログラムのことをフルサービスリゾルバ
といいます。
フルサービスリゾルバは該当のデータが見つかるまでほかの権威DNSサーバーへ問い合わせを繰り返し、引き当たったIPアドレスをスタブリゾルバに返します。 それをスタブリゾルバが端末に返すことで、リクエストを送信した端末がアクセス先のIPアドレスが何であるかを把握し、Webページにアクセスできるという仕組みです。 イメージは下記です
サーバーからデータを受け取る
ここまでリクエストを送信することに特化して解説していました。 ここではリクエストを受け取った後のことを説明しようと思います
Webサイトが表示するためにはレスポンスを返却する必要があります
ブラウザにはメッセージを送信する機能がないため、OSに送信を依頼します。
OSがメッセージを送信するための通信プロトコル郡をプロトコルスタック
と呼びます。
データの送信をしたいときは上のレイヤから下のレイヤへ送信を依頼することで、データ送信をしています
HTTPリクエストを送信したい場合は、Socketライブラリを使用してデータを送信します。 データ通信時には受信側/送信側の両方でソケットというデータの出入り口を作成して、それらを接続することで通信を行います。 クライアントがデータを受信するまでの流れは次の4ステップで行われます
アプリケーションは直接ソケットを触ることができないため、Socketライブラリを通してソケットの作成を行います。 ソケットはSocket関数にサーバのIPアドレスを渡すことで作成でき、ソケットの作成が完了するとソケットの識別子であるディスクリプタが返ってきます。 1つのソケットにつき1つのサーバとしか通信が行えないです
サーバのソケットに接続する。 クライアントはソケットを作成した後、サーバ側のソケットへ接続するようプロトコルスタックに依頼します。 サーバに接続する際はSocketライブラリのconnect関数にディスクリプタ、IPアドレス、ポート番号の3つを渡すことで接続を確立してくれます
データの送受信 接続確立後はソケットにデータを入れるだけで、相手にデータを届けることができます。 データの送受信を行うためにはSocketライブラリのread/write関数を使用します。 ブラウザとOSがデータのやりとりをするために、受信バッファ/送信バッファというものを使用します。 ブラウザは送信したいデータを送信バッファに書き込むことで、OSにデータを渡すことができます。 同様に、OSは受信したデータを受信バッファに書き込むことで、ブラウザにデータを渡すことができます
接続を切断する データの送受信が終了した場合にはSocketライブラリのclose関数を使うことで、接続を切り、ソケットを抹消することができます
データを受信したら、受け取ったレスポンスメッセージをもとに、受信した内容をブラウザに表示します。 これによりホームページを表示することができます