Webエンジニアのためのネットワーク基礎

いろいろ削ぎ落とした必要最低限の基礎知識の紹介。

キーワード:
`サーバー` `ヘッダー` `IPアドレス` `IPv4` `IPv6` `DHCP` `DNS` `ドメイン名` `キャッシュ` `ポート番号`

↑この辺りの語句を目/耳にしたことはあるけどよく分からない・・・という人には是非、読んでいただきたい内容！

# ネットワークとは
**クライアント**と**サーバー**の**データ**のやりとりのこと。

- **クライアント**: サービスを受けるコンピュータ（CLIやGUIで操作）
- **サーバー**: サービスを提供するコンピュータ（CLIで操作）

```:例えば・・・
            http://hoge.com/
      ____                     ____
     /   /  --------------->  |=   |
____/___/   <===============  |____|
クライアント                      サーバー
               ページの情報
```

# リクエストとレスポンス
クライアントからサーバーへの通信を**リクエスト**（上の例の`http://hoge.com/`）
サーバーからクライアントへの通信を**レスポンス**（上の例の`ページの情報`）
という。

このリクエストとレスポンスの繰り返しでネットワークは成り立っている。

```:リクエストとレスポンスの繰り返し！
                リクエスト
      ____                     ____
     /   /  --------------->  |=   |
____/___/   <===============  |____|
クライアント                      サーバー
                レスポンス
```

# データ
データには**ヘッダー**と**トレーラー**が付与されている。

- **ヘッダー**: データの送受信に必要な情報
- **トレーラー**: データが壊れずに届いたかを確認するために必要な情報

```:データ
               ┌─ JSON {...} など
 ______________⊥_______________
| ヘッダー | データの中身 | トレーラー |
 ‾‾‾T‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
    ├─ 自分の
    │   ├─ IPアドレス
    │   └─ ポート番号
    ├─ 相手の
    │   ├─ IPアドレス
    │   └─ ポート番号
    └─ 次の経由地の
        └─ MACアドレス
```
- **IPアドレス**: コンピュータを特定するための識別子
- **ポート番号**: アプリを特定するための識別子
- **MACアドレス**: 機器を特定するための識別子（製造時に付けられる物理アドレス）
- **JSON**: よく使われるデータ形式（`{key: value}`のように表される）

# 郵便物をマンションの一室に届けるイメージで！
郵便物（データ）をマンション（コンピュータ）の一室（アプリ）に届けるイメージで考えると分かりやすい。

```:データのイメージ
              データの中身      トレーラー
                ______       _______
              /__//__/|─────┤ 納品書 |
             /‾‾//‾‾/‖|      ‾‾‾‾‾‾‾
  ヘッダー    |‾‾‾‖‾‾‾|‖|
 _______    |   ‖   |‖/
|  荷札  ├───|___‖___|/
 ‾‾‾T‾‾‾       小包
    ├─ 自分の
    │   ├─ IPアドレス: 住所
    │   └─ ポート番号: 部屋番号
    ├─ 相手の
    │   ├─ IPアドレス: 住所
    │   └─ ポート番号: 部屋番号
    └─ 次の経由地の
        └─ MACアドレス: 郵便局の住所など
```
# IPアドレスとDHCP
```:こういうやつ…見たことありませんか？
110.67.242.89
```
IPアドレス*は32ビットのデータで、表記の際は8ビット毎に.（ドット）で区切り、10進数に変換する。ちなみに`110.67.242.89`を32ビットのデータに戻すと`01101110010000111111001001011001`となり、人間には分かりにくい💦。

*: これはIPv4の話。IPv4では`2^32 = 4294967296 ~ 約43億`通りのIPアドレスを表現できるが、インターネットの普及に伴い、インターネットに接続する機器が増加したため、IPアドレスが足りなくなってしまった。そこで登場したのがIPv6である。IPv6ではIPアドレスは128ビットのデータで、表記の際は16ビット毎に:（コロン）で区切り、16進数に変換する。IPv6では`2^128 = 340282366920938463463374607431768211456`通りのIPアドレスを表現できる。桁の単位すら分からない。毎秒１兆個のIPアドレスを消費したとしても、使い切るのに宇宙の歴史（約200億年）の5億倍以上の時間がかかるというのだから安心だ。（参考: [２の１２８乗](https://shuju.exblog.jp/12800436/)）
___
Q. IPアドレスは、いつ、誰が決めるの・・・？
A. **DHCP**によって動的かつ一意に割り当てられる。

```:DHCP
             IPアドレスください
      ____                     ____    （アドレスプールから選ぶ）
     /   /  --------------->  |=   ├───────────┘
____/___/   <===============  |____|
クライアント                    DHCPサーバー（ルーター）
            君のIPアドレス、コレね
             110.67.242.89
```
※割り当てられるIPアドレスは期限付き。（割り当てたのに使われていないIPアドレスがあるともったいないため。）

- **DHCP**: IPアドレスを動的かつ一意に割り当てるプロトコル

# ドメイン名とDNS
実は上の例の`http://hoge.com/`でのサーバーとの通信の図は「厳密には」間違っている。

```:上の例
            http://hoge.com/
      ____                     ____
     /   /  --------------->  |=   |
____/___/   <===============  |____|
クライアント                      サーバー
               ページの情報
```
`http://hoge.com/`は**ドメイン名**といって、IPアドレスを人間に分かりやすくしたものである。そのため、通信の際には`http://hoge.com/`をIPアドレスに変換してからサーバーと通信する必要がある。この「ドメイン名をIPアドレスに変換する仕組み」のことを**DNS**という。

我々がドメイン名をWebブラウザアプリのアドレスバーに入力するだけでページの情報が返ってくる（これを名前解決という。）のはこのDNSのおかげである。よく使われる名前解決として`http://localhost/`が挙げられる。

```:DNS
            http://hoge.com/
      ____                     ____
     /   /  --------------->  |=   |
____/___/               ====  |____|
クライアント              //     DNSサーバー
                     //
                    //  この「ドメイン名」は「125.10.0.8」やな
\キャッシュとして保存/   //  いちいち聞かれると大変やから
      ____        //   保存しといてや
     /   /       //
____/___/   <====
クライアント
```
- **DNS**: ドメイン名をIPアドレスに変換するプロトコル
- **キャッシュ**: 1度尋ねたドメイン名とIPアドレスの対応関係はキャッシュとして保存される。

# ポート番号
```:こういうやつ…といってもただの数字にしか見えないけど💦
http://localhost:8000/
                 ‾‾‾‾ この部分
```
Q. そもそも何のためにあるの・・・？
A.
通信が、どのアプリからどのアプリへの通信なのかを特定するため。
クライアントは1つのコンピュータでWebブラウザアプリやメールアプリを使用する。この場合、IPアドレスが変わらないため、ポート番号によってどのアプリなのかを区別する必要がある。

Q. ポート番号は、いつ、誰が決めるの・・・？
A.

- クライアント側: 動的に割り当てられる。（**動的/プライベートポート番号**）
- サーバー側: 種類によって決まっている（**ウェルノウンポート番号**）

**ポート番号の種類**

| 番号   | 種類   | 用途   |
|:--|:--|:--|
| 0     ~ 1023  | ウェルノウンポート番号     | サーバーアプリが使用 |
| 1024  ~ 49151 | 予約済みポート番号       | 特定のアプリが使用（クライアント/サーバー問わず） |
| 49152 ~ 65535 | 動的/プライベートポート番号 | クライアントアプリが使用 |

**代表的なウェルノウンポート番号**

| 番号   | 用途   |
|:--|:--|
| 20  | FTP（データ転送）   |
| 21  | FTP（制御）        |
| 25  | SMTP（メール）      |
| 53  | DNS              |
| 67  | DHCP             |
| **80**  | **HTTP（Web）** |
| 110 | POP3（メール）        |



# 参考
**TCP/IPの4つのレイヤー**

| 階層名   | 代表的なプロトコル   | 備考   |
|:--|:--|:--|
| アプリケーション層 | DHCP、DNS | ユーザーにサービスを提供する |
| トランスポート層 | **TCP**、**UDP** | アプリを識別する（w/ポート番号） |
| インターネット層 | IP | 最終宛先を識別する（w/IPアドレス） |
| ネットワークインターフェイス層 | **イーサネット（LAN）** | 経由地を識別する（w/MACアドレス） |

- **TCP**: 確実にデータをやり取りする仕組み。「確認応答」「再送」「シーケンス番号」から成る。
- **UDP**: 高速にデータをやり取りする仕組み。動画のリアルタイム配信等に用いられる。
- **イーサネット（LAN）**: 有線のネットワークで使われるプロトコル。
  - 凸 ← こういう端子がついている機器はイーサネット（LAN）に対応している。
  - 無線LANでは`IEEE 802.11`というプロトコルが使われる。

IPに含まれる
`IPアドレス`（`CIDER表記`）
`ルーター`（`ルーティング` `ゲートウェイ`）
`踏み台サーバー`
等についてはTBE。