TCP / UDP(トランスポート層)
IP がパケットを「届くかもしれない」レベルで転送するのに対し、 トランスポート層はプロセス間で信頼性ある通信や軽量な通信を提供する。TCP / UDP / QUIC を一通り。
役割
- ポート番号でホスト内のプロセスを識別
- 多重化(複数プロセスが同時に使える)
- TCP は信頼性 / 順序 / フロー制御 / 輻輳制御
- UDP は最小限(速さ重視)
ポート番号
16 ビット = 0〜65535。
| 範囲 | 名称 | 用途 |
|---|---|---|
| 0〜1023 | Well-known | HTTP=80, HTTPS=443, SSH=22, DNS=53, SMTP=25... |
| 1024〜49151 | Registered | MySQL=3306, PostgreSQL=5432, Redis=6379... |
| 49152〜65535 | Dynamic / Ephemeral | クライアント側が自動で取る |
よく使うポート
| 20/21 | FTP |
| 22 | SSH |
| 23 | Telnet |
| 25 | SMTP |
| 53 | DNS (UDP/TCP) |
| 67/68 | DHCP |
| 80 | HTTP |
| 110 | POP3 |
| 143 | IMAP |
| 443 | HTTPS / HTTP/3 (UDP) |
| 465 / 587 | SMTPS / SMTP submission |
| 993 / 995 | IMAPS / POP3S |
| 3389 | RDP |
TCP(Transmission Control Protocol)
コネクション指向 + 信頼性ありのストリーム型。HTTP / HTTPS / SSH / SMTP の土台。
特徴
- 順序を保証(受信側で並べ直す)
- 欠落時は再送
- フロー制御(受信側のキャパに合わせる)
- 輻輳制御(ネットワークの混雑に合わせる)
- ストリーム指向(メッセージ境界はない)
3-way ハンドシェイク
TCP は通信開始前に3 回の往復でコネクションを確立する。
Client Server
| |
|---- SYN (seq=x) ------>|
| |
|<- SYN+ACK (seq=y, ack=x+1)
| |
|--- ACK (ack=y+1) ------>|
| |
|==== コネクション確立 =====|
| |
|--- アプリ通信 ---------->|
この間で 1.5 RTT。HTTPS だと TLS のハンドシェイクが追加でかかる。
4-way 切断
Client Server
|---- FIN ------------->|
|<--- ACK --------------|
| |
|<--- FIN --------------|
|---- ACK ------------->|
| |
|== TIME_WAIT (2MSL) ==|
TIME_WAIT: 古い遅延パケットが新しい接続に紛れ込まないよう、最後のソケットがしばらく残る。
高負荷サーバではこの数が問題になる(→ SO_REUSEADDR / SO_REUSEPORT)。
TCP コネクションの状態
netstat -an で見える状態。
- LISTEN — 待ち受け
- SYN-SENT / SYN-RECV — ハンドシェイク中
- ESTABLISHED — 通信中
- FIN-WAIT-1 / 2 / CLOSE-WAIT / LAST-ACK / CLOSING — 切断中
- TIME-WAIT — 切断後の待ち
- CLOSED — 完了
シーケンス番号と再送
- 送信されたバイトに連番が振られる
- 受信側は ACK で「ここまで受け取った」を返す
- 一定時間 ACK が来なければ再送
- RTT を測って再送タイムアウト (RTO) を動的調整
- SACK(Selective ACK)で部分的な再送が可能
フロー制御(受信ウィンドウ)
受信側のバッファ余裕を Window Size として返し、送信側はそれを超えて送らない。
- 受信が遅れれば Window が狭くなる → 送信元が制御
- 窓 0 が長く続くとデッドロック → Zero Window Probe で打診
- Window Scaling で 64KB 制限を超える
輻輳制御
ネットワーク全体の混雑を避けるため、送信レートを動的に変える仕組み。
- Slow Start — 最初は少しずつ増やす
- Congestion Avoidance — 線形増加
- パケットロスを検知すると急減
- アルゴリズム: Reno / CUBIC(Linux 既定)/ BBR(Google 提案、現代の主流)
Nagle / Delayed ACK
- Nagle: 小さいパケットをまとめて送る最適化(インタラクティブ通信では遅延の原因に)
TCP_NODELAYで無効化(Telnet / SSH / RTT 重視のアプリ)- Delayed ACK: ACK をすぐ返さず数十ms 待つ → Nagle と組み合わさると 200ms 級の遅延に
UDP(User Datagram Protocol)
コネクションレス + 信頼性なし + 順序保証なしの軽量プロトコル。
UDP ヘッダ(8 バイトだけ)
+-----------------+-----------------+
| Source Port (16)| Dest Port (16) |
+-----------------+-----------------+
| Length (16) | Checksum (16) |
+-----------------+-----------------+
| データ
UDP の特徴
- ハンドシェイクなし、即座に送信
- パケットが届かない / 順序が乱れる可能性あり(アプリで対処)
- ブロードキャスト・マルチキャスト可能
- ヘッダが小さい(8 B)
UDP の用途
- DNS(小さい問い合わせ)
- NTP(時刻同期)
- DHCP
- VoIP / RTP / SRT(音声・映像 — 遅延が命)
- オンラインゲーム
- QUIC / HTTP/3
- WebRTC(メディア部分)
TCP vs UDP まとめ
| TCP | UDP | |
|---|---|---|
| 接続 | あり (3-way) | なし |
| 順序 | 保証 | 保証なし |
| 再送 | あり | なし |
| 遅延 | 大きい | 小さい |
| オーバーヘッド | 20+ B | 8 B |
| 用途 | 確実性が要る | 速度・リアルタイム |
QUIC
Google が開発し IETF で標準化(RFC 9000)されたUDP 上のトランスポートプロトコル。 HTTP/3 の土台。
- UDP ベースだが TCP 並みの信頼性 + TLS 1.3 を内蔵
- 0-RTT 接続再開(過去にやり取りした相手なら即送信)
- ストリーム多重化(HTTP/2 の「Head-of-Line ブロッキング」を解消)
- 接続 ID によりIP 変更でも継続(Wi-Fi → 4G で切れない)
- OS カーネルではなくユーザ空間で実装されることが多い
SCTP / DCCP
TCP / UDP 以外のトランスポート(SCTP=複数ストリーム、DCCP=順序なし TCP)。 WebRTC のデータチャネルが SCTP を内部で使う。
ソケット
OS が提供する通信のAPI 抽象。プログラムはsocket() → bind() → listen() / connect() のように扱う。
// C の例: TCP サーバ最小
int s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, ...);
listen(s, 128);
int c = accept(s, ...);
read(c, buf, 1024);
write(c, "hello", 5);
close(c);
Node.js / TypeScript で TCP / UDP
TCP
import net from "node:net"
const server = net.createServer((socket) => {
socket.write("hello\n")
socket.on("data", (d) => console.log(d.toString()))
})
server.listen(3000)
// クライアント
const client = net.createConnection({ port: 3000 })
client.write("hi")
UDP
import dgram from "node:dgram"
const sock = dgram.createSocket("udp4")
sock.on("message", (msg, rinfo) => {
console.log(`recv ${msg} from ${rinfo.address}:${rinfo.port}`)
})
sock.bind(41234)
// 送信
sock.send("hello", 41234, "127.0.0.1")
確認コマンド
# 開いているポート / 接続中
ss -tnlp # Linux 推奨
netstat -tnlp # 古典版
lsof -i :3000 # 指定ポートのプロセス
# ポート疎通テスト
nc -zv host 443
nc -uzv host 53 # UDP
# ベンチ
iperf3 -s # サーバ
iperf3 -c host # クライアント
トラブル例
| 症状 | 原因 |
|---|---|
| connection refused | そのポートで LISTEN しているプロセスがない |
| connection timed out | FW / 経路 / 宛先サーバ停止 |
| RST が返る | サーバがコネクションを拒否 |
| 遅延が大きい | RTT、帯域、輻輳、Nagle/DelayedACK |
| TIME_WAIT が大量 | 短時間に大量接続。SO_REUSEADDR 等で対策 |
| UDP で届かない | NAT で経路維持できず、保持タイマー切れ |
「TCP は安心、UDP は速い」。HTTP/3 は UDP の上で TCP 級の信頼性を再構築した形で、 今後の Web プロトコルの主流になる。