【Goで学ぶコンピューターサイエンス】ネットワークの基礎

## **ネットワークの種類**

### **LAN（ローカルエリアネットワーク）**  
- 一般的には、家庭やオフィスなど、限定された範囲で使われるネットワーク
- 例: 自宅のWi-Fiルーターに接続されたPCやスマホ同士の通信

### **WAN（広域ネットワーク）**  
- 地理的に離れた場所同士をつなぐネットワーク。インターネットはWANの一種です
- 例: 複数のオフィスをつなぐ企業の専用回線
- 通信距離が長いため、遅延や速度の制約を受ける場合があります

### **インターネット**  
- 世界中のLANやWANが結びついた巨大なネットワーク
- データ通信の基本プロトコルである**TCP/IP**を利用しており、サーバーやクライアント間のやり取りを可能にしています

## ネットワークの構成要素

### **IPアドレス**
- **IPアドレス**は、ネットワーク内のデバイスを一意に識別するための番号です
- **IPv4**（例: `192.168.1.1`）は32ビットで構成され、約43億個のアドレスを提供します
- **IPv6**（例: `2001:0db8::1`）は128ビットで構成され、ほぼ無限に近いアドレス空間を持ちます

#### IPアドレスの役割
- データを送信する際に、送り先（宛先）と送り元（送信元）を指定します
- 例: 手紙を出すときに住所を書くのと同じ仕組み

### **DNS**
- IPアドレスは人間にとって覚えにくいため、**ドメイン名**（例: `www.example.com`）と対応付ける仕組みが必要です。これを実現するのがDNSです
- **DNSサーバー**は、ドメイン名を問い合わせると、その対応するIPアドレスを返します

#### DNSの仕組み
1. ユーザーがブラウザで`www.example.com`を入力
2. DNSサーバーに問い合わせて`93.184.215.14`というIPアドレスを取得
3. デバイスは取得したIPアドレスを使い、サーバーと通信します

### **ルーター**
- ルーターは、ネットワーク間でデータを中継する役割を果たします
- 家庭では、Wi-FiルーターがインターネットとLANをつなぐ中心的な役割を担っています

#### ルーターの役割
- データが適切な経路を通って目的地に届くように管理
- ネットワーク内のデバイスにIPアドレスを割り当てる

### **スイッチ**
- スイッチは、LAN内で複数のデバイスを接続し、効率的にデータをやり取りする装置です
- デバイス同士の通信を最適化するため、MACアドレス（デバイス固有の識別番号）を使って通信経路を制御します

## データ通信の仕組み

### **1. URL入力**
- ユーザーがブラウザに`https://www.example.com`を入力

### **2. DNS解決**
- DNSサーバーに問い合わせ、ドメイン名に対応するIPアドレスを取得します
- 例: `www.example.com` → `93.184.215.14`

### **3. パケットの送受信**
- データは小さな単位（パケット）に分割され、送信元から宛先に届けられます
- 宛先に届いたパケットは再構成され、元のデータに戻ります
- パケットは、通信経路上の複数のノード（ルーターやスイッチ）を経由して目的地に到達します

### **4. Webページの表示**
- サーバーから送られたデータ（HTMLや画像など）をブラウザが解釈して表示します

## プロトコル

通信の**規約**として機能するのがプロトコルです。
異なるデバイス間でデータをスムーズに送受信するための規則が定められています。

### **HTTP/HTTPS**
- **HTTP**は、Webページを転送するプロトコル
- **HTTPS**は、通信内容を暗号化し、セキュリティを強化したバージョン

### **TCP/IP**
- **TCP**は、データを分割して順序通りに届けるためのプロトコル
- **IP**は、データがどこに送られるべきかを指示するプロトコル

### **UDP**
- **UDP**は、信頼性よりも速度を重視したプロトコル
- オンラインゲームや動画配信など、リアルタイム性が重要な場面で利用されます

### **SMTP/IMAP4/POP3**
- メール送受信のためのプロトコル
- **SMTP**は、メール送信に使われます
- **IMAP4/POP3**は、メール受信に使われます

## OSI参照モデル

### **各階層の役割**
1. **物理層**: ケーブルや電波など、物理的な通信手段を扱います
2. **データリンク層**: 隣接するデバイス間の通信を担当
3. **ネットワーク層**: ルーターを介したデバイス間の通信を管理
4. **トランスポート層**: TCPを使ってデータの分割や再構成を行います
5. **セッション層**: 通信セッション（接続）の確立と維持を管理
6. **プレゼンテーション層**: データ形式の変換や暗号化を担当
7. **アプリケーション層**: アプリが直接利用する通信機能を提供

## Goサンプルコード
### HTTPリクエストを送信してレスポンスを受け取る

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	resp, err := http.Get("https://jsonplaceholder.typicode.com/posts/1")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response body:", err)
		return
	}

	fmt.Println("Response:", string(body))
}
```

```
Response: {
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
```

### HTTPサーバー
```go
package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, World! \n\nURL: %s\n", r.URL.Path)
}

func main() {
	http.HandleFunc("/", handler)

	fmt.Println("Starting server")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		fmt.Println("Error:", err)
	}
}
```

サーバー側
```
Starting server
```

クライアント側
```
Hello, World! 

URL: /
```