- 自分用読書メモ
第1章 Webブラウザがメッセージを作る
『ネットワークはなぜつながるのか』第1章の要点を、自分の理解を整理する形でまとめた読書メモ
WebブラウザがどのようにHTTPリクエストを作成し、サーバーへ送信するかを中心に扱う
概要
- ユーザーがブラウザにURLを入力すると、ブラウザはURLを解読しHTTPリクエストメッセージを構築する
- メッセージ送信のためにDNSでドメイン名からIPアドレスを取得する
- 取得したIPアドレスをもとに、OSのプロトコルスタックを通じてネットワーク送信が行われる
URLとHTTPの基本
URLの構造
- URLは「どこにアクセスするか」を示す識別子
- 例:
http://example-company.com/dir/file.html
- 省略された場合、サーバー側の設定でデフォルトファイルが返されるようになっている
よく使われるプロトコル
-
http
- hyper text transfer protocol
- Webアクセスで最も利用される
-
ftp
- file transfer protocol
- ファイルのアップロードやダウンロードに使用
-
mailto
- メール送信用
- 例:
mailto:example@example.com
-
ws
- WebSocket通信に使用
HTTPメソッドとリクエスト構造
- HTTPは「何を(URI)」「どうするか(メソッド)」を指定して動作する
- URI (Uniform Resource Identifier) はアクセス対象のリソースを示す
- メソッドはサーバーへの操作内容を指定する
主なHTTPメソッド
-
GET
- URIで指定した情報を取得
- ファイルやプログラムの実行結果を返す
-
POST
- クライアントからサーバーへデータを送信
-
HEAD
- ヘッダー情報のみを取得
-
OPTIONS
- 通信可能なメソッドなどの情報を取得
-
PUT
- 指定したリソースを新規作成または更新
-
DELETE
- 指定したリソースを削除
-
TRACE
- リクエスト内容をそのまま返し、プロキシでの変化を確認
-
CONNECT
- 暗号化通信のトンネルを確立(HTTPSなど)
HTTPリクエストは「URI + メソッド」で構成され、ブラウザが構築してサーバーに送信する
リクエスト例(GET)
GET /cgi/sample.cgi?Field1=ABCDE HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Field1=ABCDE
レスポンス概要
- サーバーはリクエストを処理し、HTTPレスポンスを返す
- ステータスコードで処理結果を表す
- 1xx: 処理中
- 2xx: 正常終了(200 OKなど)
- 3xx: リダイレクト
- 4xx: クライアントエラー(404 Not Foundなど)
- 5xx: サーバーエラー
IPアドレスと通信の基礎
- ブラウザはHTTPメッセージを作成できるが、送信処理はOSが担当する
- OSはIPアドレスを指定してネットワークへ送信する
- IPアドレスはTCP/IPに基づいて構成され、ネットワーク内での「住所」にあたる
IPアドレスの構造
- 例:
10.11.12.13
- 各部分は8ビット(1バイト)を10進数で表現
- ネットワーク番号とホスト番号に分かれる
- どこまでがネットワーク番号かはネットマスクで決まる
ネットマスクの例
-
10.11.12.13/255.255.255.0
- 左の1がネットワーク番号、右の0がホスト番号を表す
-
/24
のようにビット数で表すことも多い-
/24
は「24ビットがネットワーク番号」を意味する
-
特殊アドレス
-
10.11.12.0/24
はサブネット自体を示す -
10.11.12.255/24
はサブネット全体へのブロードキャストを表す
DNSによる名前解決
DNSとは
- ドメイン名からIPアドレスを取得する仕組み
- DNSサーバーに問い合わせて対応するIPアドレスを得る
リゾルバ
- アプリケーション(例: ブラウザ)から呼び出されるDNSクライアント
- 通常、OSに組み込まれているライブラリとして動作する
memory = gethostbyname("example.com")
DNSサーバーの動作
- DNSサーバーは「リソースレコード」という形式で情報を保持
- クラス: 通常は IN (インターネット)
- タイプ: A (IPv4), MX (メール), PTR, CNAME, NS, SOA など
- 問い合わせに応じてIPアドレスなどを返す
階層構造と探索
- ドメインは階層的に管理される
- 例:
www.lab.sample-company.co.jp
-
jp
→co
→sample-company
→lab
の順で階層化
-
- 例:
- ルートDNSを起点に、上位から下位へ順に問い合わせる
- キャッシュにより同じ問い合わせは高速化される
DNSはルートから順にたどる階層的システムであり、分散管理によって効率的に名前解決を行う
ソケット通信の流れ
通信のフェーズ
- ソケット作成
-
socket()
で通信の入口(ディスクリプタ)を作る
-
- 接続
-
connect()
でサーバーのIPとポート番号に接続 - Webサーバーの標準ポートは 80 (HTTP) または 443 (HTTPS)
-
- データ送信
-
write()
でリクエストメッセージを送信
-
- データ受信
-
read()
でサーバーからのレスポンスを受け取る
-
- 切断
-
close()
で接続を終了
-
memory = gethostbyname("example.com")
sock = socket(AF_INET, SOCK_STREAM, 0)
connect(sock, server_ip_port)
write(sock, http_request, length)
read(sock, buffer, size)
close(sock)
HTMLや画像など、各リソース取得ごとにこの通信処理が繰り返される
まとめ
- ブラウザはURLを解析してHTTPリクエストを構築する
- DNSで名前解決を行い、IPアドレスを取得して送信先を特定する
- OSのプロトコルスタックを介してTCP/IP通信が行われる
- これらの仕組みにより、私たちはWebページを表示できている
第2章 TCP/IPのデータを電気信号にして送る ~ プロトコル・スタックとLANアダプタを探検 ~
本章ではアプリからソケット経由で送り出されたデータが、OSのプロトコル・スタックで処理され、LANアダプタで電気信号になって相手へ届くまでの流れを整理する
概要
- 通信は概ね「ソケット作成 → 接続 → 送受信 → 切断」の順で進む
- OSのプロトコル・スタックがTCP/UDPやIP処理を担当し、最終的にイーサネットでパケットを送受信する
- LANアダプタがパケットを電気信号へ変換し、ケーブルや無線で転送する
プロトコル・スタックの構成
- アプリケーション層
- ブラウザやメーラーなどのアプリ
- SocketライブラリとDNSリゾルバを利用
- OS層
- プロトコル・スタックを実装
- TCP: 信頼性重視のストリーム通信に使用
- UDP: 軽量な制御やストリーミング用途に使用
- IP: ルーティングや分割統合を担当
- ICMP: IPレベルのエラー通知や診断に使用
- ARP: IPアドレスからMACアドレスを解決
- デバイス層
- ドライバがLANアダプタを制御
- LANアダプタが実際の送受信を実行
ソケットの実態と確認
- プロトコル・スタックは各接続ごとに制御情報を保持する
- 例: 相手のIP/ポート、状態、タイムアウト、再送制御など
- この制御情報の集合がソケットの実体と考えられる
- Windows例:
netstat -ano
で状態を確認できる- Proto: TCP か UDP
- Local Address: 自ホストのIPとポート
- Foreign Address: 相手のIPとポート(UDPは
:*
になることがある) - State: LISTENING, ESTABLISHED など
- PID: プロセス識別子
netstat -ano
# Proto Local Address Foreign Address State PID
# TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 984
ソケット作成と接続
ソケット作成
-
socket()
を呼び出すとプロトコル・スタックがソケット用の記憶領域を確保し初期化する - 以後は返却されたディスクリプタを通して送受信を依頼する
接続確立(クライアント側)
-
connect(ディスクリプタ, サーバーIPとポート)
を呼ぶ - TCPヘッダーのコントロールビット SYN を 1 にして接続要求を送る
- 必要なシーケンス番号やウィンドウサイズも設定する
接続確立(サーバー側)
- 受信したパケットをIP → TCPの順で解釈し、該当ソケットへ紐づける
- SYN を受けたら ACK を 1 にして応答し、接続状態へ遷移する
- クライアントもACKを返し、三者のやり取りが完了するとコネクションが確立する
// 疑似コード
sock = socket(AF_INET, SOCK_STREAM, 0)
connect(sock, server_ip_port)
// ここでTCP 3-way ハンドシェイクが完了している想定
送受信の基本と分割
書き込みとバッファ
-
write(ディスクリプタ, データ, 長さ)
で送信を依頼 - スタックは送信バッファへ格納し、条件に応じて送出する
- MTU と MSS を目安に送信タイミングを判断
- または一定時間経過で送出
MTU と MSS
- MTU: 1フレームに載せられる最大バイト数(イーサネットなら一般的に 1500)
- MSS: MTU からIP/TCPヘッダー分を差し引いた、実際にTCPが一度に運べる最大データ量
各層でのデータ単位
- アプリ層: HTTPヘッダーとボディなど
- TCP層: アプリデータを分割し、各断片にTCPヘッダーを付与
- IP層: TCPセグメントにIPヘッダーを付与しパケット化
信頼性制御: シーケンス番号とACK
- 送信側は「何バイト目から何バイト送るか」をシーケンス番号で示す
- 受信側は受信済みの最終バイト位置をACK番号で返す
- 欠落があれば再送が行われる
- 初期シーケンス番号は推測困難な値を用いる
例: 2000バイトまで受信済みなら、次に来るべきシーケンスは 2001 と判断する
スループット向上: ウィンドウ制御
- 応答待ちで停止する「ピンポン方式」は待機時間が増えやすい
- 受信側はウィンドウサイズで受け取れる量を広告し、送信側はACKを待たずに一定量を連続送信できる
- ACK番号とウィンドウ広告を併用して効率を高める
受信とアプリケーションへの受け渡し
- 分割されたパケットが到着すると、TCPはシーケンス番号で並べ直し、欠落があれば再送要求を促す
- 受信バッファに溜まったデータはアプリが
read()
で取得する - 取得完了やエラーはアプリに通知される
write(sock, http_request, length)
read(sock, buffer, size) // レスポンス受信
切断の手順
- 送信完了後、片側から切断手続きに入る
- 切断側はTCPヘッダーの FIN を 1 にして送信し、相手はACKで応答する
- 反対方向のデータも終われば相手からもFINが届き、ACKで応答して完了する
- 一定時間の猶予後にソケットは抹消される
close(sock)
IP と イーサネットの役割分担
- IPは最終的な宛先IPアドレスを維持しつつ、次に送るべき中継装置へルーティングを決める
- イーサネットは同一サブネット内で次の中継装置やホストまでフレームを届ける
- 送出ごとに MACヘッダー の宛先は「次ホップ」のMACアドレスへ更新される
- 宛先IPは変えず、MACアドレスはホップごとに更新する
ARP によるMACアドレス解決
- 同一サブネット内の相手MACアドレスは ARP で解決する
- ブロードキャストで「このIPの人は誰か、MACを教えて」と問い合わせる
- 応答でMACアドレスを得る
- 解決結果はキャッシュし、以降の送信で再利用する
IPヘッダーと経路情報
- IPヘッダーにはバージョン、ヘッダー長、送受信IP、TTL、プロトコル番号などが含まれる
- ホストは複数のLANアダプタを持つ場合があり、それぞれにIPが割り当てられる
- 経路は
route print
等で確認できる
イーサネットフレームとMACヘッダー
- MACヘッダーは宛先/送信元MACアドレスとタイプを持つ
- タイプ例: 0x0800 = IPv4, 0x0806 = ARP
- スイッチングハブは宛先MACに応じたポートだけに転送する
- リピータハブは全ポートにフラッディングする
LANアダプタの内部
- バッファメモリに送受信フレームを一時保存
- ROMに固有のMACアドレスを格納
- MAC回路が衝突検知や再送などを制御
- PHY回路が物理層の送受信を担当
- RJ-45などのコネクタでケーブルと接続
電気信号化の直前に付く制御情報
-
プリアンブル
-
1010...
が連続する同期用ビット列
-
-
スタートフレームデリミタ
- フレーム開始を示すマーカー
-
FCS
- 受信側が誤り検出に用いるチェック値
- これらを付与してPHYが媒体へ送出する
受信時の処理
- 受信側LANアダプタは割り込みでCPUに通知し、フレームをバッファへ搬入する
- タイプフィールドで上位プロトコルを識別し、IP → TCP/UDP へ渡す
- IPで分割されたデータはフラグメント情報を使って再構成する(リアセンブリング)
- IP層で致命的な問題があれば ICMP で通知する
UDP の位置づけ
- ヘッダーは送信元/宛先ポート、長さ、チェックサムのみの軽量プロトコル
- 再送や順序制御を持たず、リアルタイム性を優先する用途に向く
- 例: DNSクエリ、音声や映像のストリーミングなど
- 欠落が一時的でも全体として許容できる場面で活用する
- 今後、加筆する
第3章 ケーブルの先はLAN機器だった~ハブとスイッチ、ルーターを探検~
- 割愛
第4章 アクセス回線を通って、インターネットの内部へ~アクセス回線とプロバイダを探検~
- 割愛
第5章 サーバー側のLANには何がある
- 割愛
第6章 webサーバーに到着し、応答データがwebブラウザに戻る~わずか数秒の「長い旅」の終わり~
- 割愛