【初心者向け】TCP通信の基本とURIの仕組み

インターネットの世界では様々なコンピュータが通信していますが、その裏側ではどのようなことが起きているのでしょうか？今回は、Web通信の基盤となるTCPと、Webアドレスの仕組みであるURIについて初心者向けに解説します。

## TCPとは？

TCP（Transmission Control Protocol）は、インターネット上でデータを確実に送受信するための約束事（プロトコル）です。WebサイトやメールなどのサービスはこのTCPの上で動いています。

**TCPの主な特徴：**
- 信頼性が高い（データの欠損や順序の入れ替わりを防ぐ）
- 双方向通信が可能
- 接続確立→データ転送→接続終了という流れがある

## TCPの接続確立（3ウェイハンドシェイク）

TCPで通信を始める前に、「本当に相手と通信できますか？」と確認し合う儀式があります。これを「3ウェイハンドシェイク」と呼びます。

### Step 1: SYNパケットの送信

クライアント（あなたのブラウザなど）がサーバーに「通信したいです！」と言う最初の挨拶です。

```
クライアント → SYN → サーバー
```

**SYNパケットに含まれる情報：**
- 「私はあなたと通信を始めたいです」という意思表示
- 初期シーケンス番号（データの順番を管理するための番号）

これは人間の会話でいうと「もしもし、聞こえますか？」のようなものです。

### Step 2: SYN+ACKパケットの送信

サーバーがクライアントに「はい、通信できますよ！こちらも準備OKです」と返事します。

```
クライアント ← SYN+ACK ← サーバー
```

**SYN+ACKパケットに含まれる情報：**
- 「あなたの通信要求を受け取りました（ACK）」
- 「私もあなたと通信を始めたいです（SYN）」
- サーバーの初期シーケンス番号

人間の会話では「はい、聞こえていますよ。こちらの声は聞こえますか？」のような意味です。

### Step 3: ACKパケットの送信

クライアントがサーバーに「はい、あなたの声も聞こえています！これで会話を始められますね」と最終確認します。

```
クライアント → ACK → サーバー
```

**ACKパケットに含まれる情報：**
- 「あなたの準備完了の返事を受け取りました」

これで3ウェイハンドシェイクが完了し、本格的なデータのやり取りが始まります。

## TCPとHTTPの関係

HTTPはTCPの上で動作するプロトコルです。関係を簡単に図で表すと：

```
アプリケーション層：HTTPプロトコル（Webブラウジング）
↓
トランスポート層：TCPプロトコル（信頼性のある通信）
↓
インターネット層：IPプロトコル（パケットの配送）
↓
ネットワークインターフェース層：イーサネットなど（物理的な通信）
```

### HTTPリクエストが送られるまでの流れ

Webサイトにアクセスするときの裏側の流れを見てみましょう：

1. **DNS解決**: `www.example.com` → `93.184.216.34` のようにドメイン名をIPアドレスに変換

2. **TCPコネクション確立**:
   - クライアント → SYN → サーバー
   - クライアント ← SYN+ACK ← サーバー
   - クライアント → ACK → サーバー

3. **HTTPリクエスト送信**:
   ```
   GET / HTTP/1.1
   Host: www.example.com
   User-Agent: Mozilla/5.0 ...
   ```

4. **HTTPレスポンス受信**:
   ```
   HTTP/1.1 200 OK
   Content-Type: text/html
   ...
   
   <!DOCTYPE html>
   <html>...
   ```

5. **TCPコネクション終了** (データのやり取りが終わったら)

## URIとは？

URI（Uniform Resource Identifier）は、インターネット上のリソース（Webページ、画像、APIなど）を識別するための文字列です。URLはURIの一種で、特にリソースの「場所」を示します。

### URIの構造

一般的なURIの構造は以下のようになっています：

```
scheme://authority/path?query#fragment
```

例: `https://www.example.com:443/search?q=tcp&lang=ja#results`

- **scheme**: `https` （通信プロトコル）
- **authority**: `www.example.com:443` （ホスト名とポート番号）
- **path**: `/search` （リソースのパス）
- **query**: `q=tcp&lang=ja` （クエリパラメータ）
- **fragment**: `results` （ページ内の特定部分を指定）

### リクエストURI

HTTPリクエストでは、URI全体ではなく「リクエストURI」という部分だけを使用することがあります。これは主にパスとクエリ部分を指します。

例えば、以下のようなHTTPリクエスト：

```
GET /search?q=tcp&lang=ja HTTP/1.1
Host: www.example.com
```

ここでの `/search?q=tcp&lang=ja` がリクエストURIです。

サーバー側では、このリクエストURIを解析して適切なリソースを返します。例えば：
- `/search` → 検索ページを表示
- `q=tcp` → 「tcp」というキーワードで検索
- `lang=ja` → 日本語の結果を表示

### パーセントエンコーディング（URLエンコーディング）

URIには使用できない文字があります。例えば、日本語や空白、特殊記号などです。これらの文字は「パーセントエンコーディング」という方法で変換されます。

**主な変換例：**
- 空白 → `%20` 
- 日本語「あ」 → `%E3%81%82`
- `+` → `%2B`
- `?` → `%3F`
- `&` → `%26`
- `=` → `%3D`

例えば、「TCP 通信」という検索キーワードは：
```
https://www.example.com/search?q=TCP%20%E9%80%9A%E4%BF%A1
```

のようにエンコードされます。

**なぜ必要？**
- URIは ASCII文字のみで構成される必要がある
- 特殊文字（&や=など）がクエリパラメータの区切りと混同されるのを防ぐ
- 異なるシステム間で統一的に解釈できるようにする

## まとめ

- **TCP**：信頼性の高いデータ通信の仕組み。SYN, ACK, SYN+ACKといったパケットを使って接続を確立する「3ウェイハンドシェイク」が特徴。
  
- **TCPとHTTP**：HTTPはTCPの上で動作するプロトコル。Webページを表示する前にTCP接続が確立される。

- **URI**：インターネット上のリソースを一意に識別する文字列。scheme, authority, path, query, fragmentなどの部分から構成される。

- **リクエストURI**：HTTPリクエストで使用されるURI部分。主にパスとクエリパラメータを含む。

- **パーセントエンコーディング**：URIで使用できない文字を%記号と16進数で表現する方法。