데이터가 계층을 내려갈 때마다 그 계층의 헤더를 덧붙이는 것. 계층 모델이 실제로 동작하는 방식이다.
내려가며 옷을 입는다
응용 [ HTTP 요청 "GET /index.html" ]
↓ TCP 헤더를 붙인다 (포트 · 순서번호)
전송 [ TCP헤더 | HTTP 요청 ] ← 세그먼트
↓ IP 헤더를 붙인다 (출발지·목적지 IP)
인터넷 [ IP헤더 | TCP헤더 | HTTP 요청 ] ← 패킷
↓ 이더넷 헤더·트레일러를 붙인다 (MAC 주소)
링크 [ 이더넷헤더 | IP헤더 | TCP헤더 | HTTP | FCS ] ← 프레임
받는 쪽은 정확히 반대 순서로 벗긴다(역캡슐화). 각 계층은 자기 헤더만 읽고 나머지는 그냥 "내용물"로 취급한다.
두 모델
OSI 7계층 (개념 모델) TCP/IP 4계층 (실제 구현)
7 응용 응용 (HTTP · DNS · TLS)
6 표현
5 세션
4 전송 전송 (TCP · UDP)
3 네트워크 인터넷 (IP · ICMP)
2 데이터링크 링크 (이더넷 · Wi-Fi)
1 물리
실무에서 쓰는 건 TCP/IP 4계층이고, OSI는 "L4 로드밸런서"·"L7 프록시"처럼 층을 가리키는 공용어로 남아 있다.
왜 나누나
- 각 계층이 자기 일만 한다 — IP 는 경로만, TCP 는 신뢰성만
- 한 계층을 통째로 갈아 끼울 수 있다
- 유선 → 무선으로 바꿔도 위 계층은 그대로다
- IPv4 → IPv6 로 바꿔도 HTTP 는 안 바뀐다
- 표준을 나눠 만들 수 있다
헤더는 공짜가 아니다
이더넷 14 + IP 20 + TCP 20 = 최소 54바이트
1바이트를 보내려 해도 55바이트가 나간다
- 작은 패킷을 잦게 보내면 오버헤드가 지배적이 된다
- 그래서 TCP 는 작은 데이터를 모아 보내려 한다 (Nagle 알고리즘)
진단도 계층으로 쪼갠다
ping example.com # 3계층 — IP 로 닿는가
telnet example.com 443 # 4계층 — 포트가 열려 있는가
openssl s_client -connect example.com:443 # TLS 가 서는가
curl -v https://example.com # 7계층 — 응답이 오는가
"안 된다"를 아래 계층부터 하나씩 확인하는 것이 네트워크 문제 해결의 기본기다.
면접 함정
- ❌ "OSI 7계층이 실제 구현" → 개념 모델이고, 구현은 TCP/IP 4계층이다.
- ❌ "세션·표현 계층은 아무것도 안 한다" → 그 기능이 응용 계층 안으로 흡수됐을 뿐이다(TLS가 대표적).
실제 패킷으로 확인하기
sudo tcpdump -i any -X -c 1 'tcp port 80'
0x0000: aabb cc11 2233 ddee ff44 5566 0800 ← 이더넷 헤더 14바이트 (목적지MAC 출발지MAC 타입)
0x000e: 4500 0034 ... ← IP 헤더 (4=IPv4, 5=헤더길이 20바이트)
0x0022: 0050 c1b4 ... ← TCP 헤더 (0050 = 포트 80)
0x0036: 4745 5420 2f20 4854 5450 ← 페이로드 "GET / HTTP"
바이트를 직접 보면 캡슐화가 추상 개념이 아니라는 게 분명해진다. 각 계층의 헤더가 실제로 앞에 붙어 있다.
계층을 넘나드는 것들
-
원칙적으로 각 계층은 위아래만 안다. 그런데 현실에는 예외가 있다
-
TCP 체크섬 — IP 헤더의 일부(의사 헤더)를 계산에 포함한다 — 계층 침범
-
NAT — 4계층 포트를 고쳐 3계층 주소 변환을 한다
-
L7 로드밸런서 — 7계층 내용을 보고 4계층 연결을 나눈다
-
"깨끗한 계층" 은 이상이고, 성능·현실 제약이 경계를 흐린다