IT Knowledge/Network/images/03-tcp와-udp-venn.svg
TCP와 UDP
학습 목표
- TCP와 UDP의 차이점을 일상적인 비유로 이해하기
- TCP 3-way handshake와 4-way handshake 상세 과정 파악하기
- TCP의 신뢰성 메커니즘(순서 번호, ACK, 재전송) 이해하기
- UDP의 특징과 사용 사례 파악하기
- 포트와 소켓의 개념 이해하고 실전 예시 작성 가능
Part 1: 전송 계층의 역할
🤔 전송 계층은 왜 필요한가요?
핵심 질문:
데이터가 컴퓨터 A에서 컴퓨터 B로 전송될 때 어떤 문제들이 발생할 수 있을까요?
📋 발생 가능한 문제
| 문제 | 설명 | 해결책 필요 |
|---|---|---|
| 데이터 손실 | 전송 중 데이터가 유실됨 | 재전송 메커니즘 |
| 순서 뒤바뀜 | 데이터가 도착 순서가 뒤바뀜어짐 | 순서 번호 |
| 중복 전송 | 동일 데이터가 여러 번 수신됨 | 중복 검출 |
| 혼잡 제어 | 송신 측이 너무 빠르게 보내면 받는 쪽이 감당 못함 | 흐름 제어, 혼잡 제어 |
| 과도 전송 | 불필요한 데이터 전송으로 네트워크 혼잡 | 속도 조절 |
🎯 전송 계층의 해결책
전송 계층의 핵심 역할:
- 신뢰성 보장: 데이터가 정확하게 도착하는지 확인
- 순서 보장: 데이터가 올바른 순서로 도착
- 혼잡 제어: 네트워크 부하를 적절하게 관리
Part 2: TCP와 UDP의 핵심 차이점
📊 TCP vs UDP 비교
| 특성 | TCP (Transmission Control Protocol) | UDP (User Datagram Protocol) |
|---|---|---|
| 연결 방식 | 연결 지향 (Connection-oriented) | 비연결형 (Connectionless) |
| 신뢰성 | 높음 (재전송, 순서 보장) | 낮음 (재전송 없음, 순서 보장 없음) |
| 속도 | 상대적으로 느림 (헤더 오버헤드) | 빠름 (헤더 작음) |
| 헤더 크기 | 20-60바이트 | 8바이트 |
| 사용 사례 | 웹, 이메일, 파일 전송 | 실시간 스트리밍, DNS, VoIP |
| 전송 단위 | 바이트 스트림 (Byte Stream) | 데이터그램 (Datagram) |
🎯 일상적인 비유: 택배 서비스 vs 우편 서비스
TCP = 택배 서비스 (등기 우편)
특징:
- 등기: 보내는 사람과 받는 사람의 정보를 확인
- 추적 가능: 현재 배송 위치 추적
- 배달 보장: 분실 시 재배송
- 순서 보장: 보내는 순서대로 도착
- 비용: 더 비쌈 (추적, 관리 비용)
실제 사용 예시:
중요한 이메일: "계약서 전송" → TCP
파일 다운로드: "프로젝트 보고서" → TCP
웹 페이지: "뉴스 기사" → TCP
UDP = 우편 (일반 우편)
특징:
- 빠름: 편지를 바로 우체통에 넣고 보냄
- 추적 없음: 편지가 어디서 처리되는지 모름
- 분실 시 재발송 안됨: 우체국에 넣으면 끝
- 순서 보장 없음: 먼저 보낸 편지가 나중에 도착 가능
- 저렴: 단순히 편지를 보내기만 하니까
실제 사용 예시:
실시간 채팅: "라이브 스트리밍" → UDP
DNS 쿼리: "도메인 네임 → IP 주소" → UDP
온라인 게임: "실시간 위치 정보" → UDP
VoIP: "인터넷 전화" → UDP
Part 3: TCP 상세 분석
🔄 TCP 3-way Handshake (연결 설정)
🎯 왜 3-way Handshake가 필요한가요?
문제: 두 사람이 전화로 대화하려면 어떻게 할까요?
답:
- A가 B에게 전화 (연결 요청)
- B가 전화를 받음 (요청 승인)
- A가 통화를 받음 (승인 확인)
TCP 3-way Handshake:
클라이언트 → 서버: SYN (Synchronize) [Step 1]
서버 → 클라이언트: SYN-ACK (Synchronize-Acknowledgment) [Step 2]
클라이언트 → 서버: ACK (Acknowledgment) [Step 3]
↓
연결 성립!
📋 각 단계 상세 설명
Step 1: 클라이언트 → 서버: SYN
- 의미: “연결 요청합니다”
- 내용:
- 클라이언트의 초기 순서 번호(ISN) 포함
- “이 순서 번호부터 보내겠습니다”
Step 2: 서버 → 클라이언트: SYN-ACK
- 의미: “연결 요청 승인합니다”
- 내용:
- 서버의 초기 순서 번호(ISN) 포함
- 클라이언트의 순서 번호 + 1 (ACK)로 승인
Step 3: 클라이언트 → 서버: ACK
- 의미: “승인 확인합니다”
- 내용:
- 서버의 순서 번호 + 1 (ACK)로 최종 승인
💡 실제 예시로 이해하기
상황: 웹 브라우저에서 “https://www.example.com” 접속
TCP 3-way Handshake 과정:
[클라이언트] [서버]
│ │
│─── SYN (ISN=1000) ───────────────>│
│ │
│<── SYN-ACK (ISN=2000, ACK=1001) ──│
│ │
│─── ACK (ACK=2001) ─────────────────>│
│ │
│ 연결 성립! │
│ │
│─── HTTP GET 요청 ──────────────────>│
│ │
│<── HTTP 200 OK 응답 ────────────────│
│ │
│ 데이터 전송 완료 │
🔄 TCP 4-way Handshake (연결 종료)
TCP 4-way Handshake:
클라이언트 → 서버: FIN [Step 1]
서버 → 클라이언트: ACK [Step 2]
서버 → 클라이언트: FIN [Step 3]
클라이언트 → 서버: ACK [Step 4]
↓
연결 종료!
📋 각 단계 상세 설명
Step 1: 클라이언트 → 서버: FIN
- 의미: “연결 종료 요청합니다”
Step 2: 서버 → 클라이언트: ACK
- 의미: “종료 요청 승인합니다”
Step 3: 서버 → 클라이언트: FIN
- 의미: “연결 종료 요청합니다”
Step 4: 클라이언트 → 서버: ACK
- 의미: “종료 요청 승인합니다”
💡 TIME_WAIT 상태
정의: 4-way Handshake 완료 후 클라이언트가 잠시 대기하는 상태
목적: 서버에서 보낸 마지막 데이터가 도착했는지 확인
시간: 일반적으로 2 * MSL (Maximum Segment Lifetime)
- 보통 30초 ~ 2분
Part 4: TCP 신뢰성 메커니즘
🎯 신뢰성 보장을 위한 핵심 메커니즘
| 메커니즘 | 설명 | 실제 작동 |
|---|---|---|
| 순서 번호 | 데이터의 순서 식별 | Seq=1000, Seq=1001, Seq=1002… |
| 확인 응답(ACK) | 데이터 수신 확인 | ACK=1001 (1000번까지 수신) |
| 재전송 | 손실된 데이터 재전송 | ACK를 못 받으면 재전송 |
| 타이머아웃 | 재전송 기다이미터 설정 | 일반 3초 ~ 30초 |
| 흐름 제어 | 송신 속도 조절 | 수신 측 처리 능력에 맞춤 |
| 혼잡 제어 | 네트워크 혼잡 방지 | 송신 측 속도 감소 |
🔄 순서 번호와 ACK
📏 순서 번호 (Sequence Number)
정의: 데이터의 순서를 식별하는 번호
특징:
- 32비트 숫자
- 초기화: 랜덤(0 ~ 2^32-1)
- 증가: 데이터 크기만큼
실제 예시:
데이터: "HELLO WORLD" (11바이트)
[송신]
Seq=1000, Data="HELLO WORLD"
[수신]
ACK=1011 (1000 + 11)
🔄 재전송 메커니즘
문제 상황
클라이언트 → 서버: Seq=1000, Data=100바이트
↓
서버에서 ACK를 못 받음 (손실)
↓
클라이언트: 재전송!
🎯 재전송 전략
| 전략 | 설명 | 사용 상황 |
|---|---|---|
| 고정 타이머 | 일정 시간마다 재전송 | 완전 신뢰성 필요 |
| 지수적 백오프 | 타이머 배로 증가 | 혼잡 상황 |
| 선택적 재전송 (SACK) | 누�된 부분만 재전송 | 혼잡하지 않은 부분 |
Part 5: TCP 흐름 제어 (Flow Control)
🎯 왜 흐름 제어가 필요한가요?
문제: 서버가 매초 1GB를 받을 수 있는데, 클라이언트가 100Mbps로만 보내면?
해결책: 흐름 제어 (Flow Control)
📊 흐름 제어 메커니즘
| 메커니즘 | 설명 | 실제 작동 |
|---|---|---|
| 슬라이딩 윈도우 | 수신측 처리 능력에 맞춰 속도 | 수신 버퍼 여유 확인 |
| 윈도우 사이즈 | 한 번에 보낼 수 있는 데이터 양 | 수신측 버퍼 크기 확인 |
| 혼잡 알림 | 버퍼 부족 시 클라이언트에 알림 | ECN (Explicit Congestion Notification) |
🎯 TCP 윈도우 (TCP Window)
정의: 한 번에 보낼 수 있는 데이터 양
작동 원리:
[슬라이딩 윈도우]
수신측 버퍼: 4096바이트
↓
송신측 윈도우: 4096바이트 (수신측 버퍼 맞춤)
💡 실제 예시
상황: 대용 파일 다운로드
[초기]
Window Size: 4096
[데이터 전송]
Seq=1000, Data=4096
Seq=1496, Data=4096
[수신 확인]
ACK=1496 (1000+496)
ACK=2592 (1496+1096)
Part 6: TCP 혼잡 제어 (Congestion Control)
🎯 왜 혼잡 제어가 필요한가요?
문제: 네트워크가 혼잡하면 어떻게 될까요?
해결책: 혼잡 제어 (Congestion Control)
📊 TCP 혼잡 제어 알고리즘
| 알고리즘 | 설명 | 속도 변화 |
|---|---|---|
| Slow Start | 천천히 속도 증가 | 지수적 증가 |
| Congestion Avoidance | 혼잡 발생 시 속도 감소 | 감소 후 천천히 증가 |
| Fast Recovery | 빠르게 회복 | 급격 감소 후 빠르게 증가 |
💡 Slow Start 알고리즘
초기화: cwnd (congestion window) = 1 MSS (Maximum Segment Size)
작동 원리:
초기: cwnd = 1 MSS
[ACK 수신 시]
cwnd = 2 MSS
cwnd = 4 MSS
cwnd = 8 MSS
...
최대 cwnd = 16 MSS (일반적)
📊 혼잡 제어 단계
[Slow Start]
↓ cwnd 증가
[Congestion Avoidance]
↓ cwnd 선형 증가
[혼잡 감지 (3개의 ACK 손실)]
↓ cwnd / 2
[Fast Recovery]
↓ 빠르게 cwnd 복구
Part 7: UDP 상세 분석
🎯 UDP의 핵심 특징
정의: 비연결형, 신뢰성 없는 전송 프로토콜
특징:
- 연결 설정 없음: 데이터 바로 전송
- 재전송 없음: 데이터 손실 시 복구 안함
- 순서 보장 없음: 데이터 도착 순서 뒤바뀜 가능
- 빠름: 헤더 작음 (8바이트)
📏 UDP 헤더 구조
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Dest | Length | Checksum|
+--------+--------+--------+--------+
| Port | Port | | |
+--------+--------+--------+--------+
| Data (if any)... |
+-----------------------------------+----+
크기: 최소 8바이트, 최대 65507바이트
필드 설명:
- Source Port: 송신자 포트
- Destination Port: 수신자 포트
- Length: 데이터 + 헤더 길이
- Checksum: 데이터 무결성 검증
💡 UDP 사용 사례
| 애플리케이션 | 이유 | UDP 사용 |
|---|---|---|
| 실시간 스트리밍 | 데이터 속도 중요, 일부 손실 허용 | VoIP, 라이브 스트리밍 |
| DNS 쿼리 | 짧은 쿼리, 빠른 응답 중요 | UDP 포트 53 |
| 온라인 게임 | 실시간 위치 정보 중요 | 게임 데이터 |
| 동기화/비디오 | 버퍼링 허용 가능 | 실시간 미디어 |
| TFTP | 부팅 시 간단한 구현 | 파일 전송 |
Part 8: 포트 번호와 소켓
🎯 포트 번호
정의
포트 번호 = 애플리케이션 식별자 (0-65535)
📊 포트 번호 범위
| 범위 | 이름 | 용도 |
|---|---|---|
| 0-1023 | Well-known Ports | 시스템 서비스 (root 권한 필요) |
| 1024-49151 | Registered Ports | 등록된 애플리케이션 |
| 49152-65535 | Dynamic Ports | 클라이언트 임시 포트 |
🎯 주요 포트 번호
| 포트 | 프로토콜 | 서비스 | 사용 예시 |
|---|---|---|---|
| 20 | FTP (Data) | 파일 전송 | FTP 데이터 전송 |
| 21 | FTP (Control) | 파일 전송 | FTP 제어 |
| 22 | SSH | 원격 접속 | 리눅스 서버 접속 |
| 23 | Telnet | 원격 접속 | 라우터/스위치 설정 |
| 25 | SMTP | 이메일 송신 | 이메일 전송 |
| 53 | DNS | 도메인 네임 해석 | 도메인 → IP |
| 80 | HTTP | 웹 | 웹 브라우징 |
| 443 | HTTPS | 암호화된 웹 | 보안 웹 접속 |
| 3306 | MySQL | 데이터베이스 | MySQL 서버 |
| 5432 | PostgreSQL | 데이터베이스 | PostgreSQL 서버 |
| 6379 | Redis | 캐시 | Redis 서버 |
📋 소켓 (Socket)
정의
소켓 = IP 주소 + 포트 번호의 조합 (통신 엔드포인트)
소켓 예시
소켓 = IP 주소 + 포트 번호
= 192.168.1.100 + 8080
= 192.168.1.100:8080
소켓 유형
| 유형 | 설명 | 예시 |
|---|---|---|
| TCP 소켓 | 연결 지향, 신뢰성 | 웹 브라우저, 이메일 클라이언트 |
| UDP 소켓 | 비연결형, 빠름 | DNS, VoIP |
💡 실전 예시: 웹 브라우저와 웹 서버 통신
TCP 소켓 사용:
[클라이언트] [웹 서버]
소켓: 192.168.1.100:443 (HTTPS)
IP: 192.168.1.100
포트: 443
│
│─── 3-way Handshake ────────→│
│ │
│─── HTTP GET ────────────────→│
│ │
│←─ HTTP 200 OK ──────────────┘
Part 9: 실전 예시
🎯 예시 1: TCP 서버 구현 (Python)
import socket
import time
def tcp_server():
# 소켓 생성
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8080))
server_socket.listen(5)
print("TCP 서버 시작: 0.0.0.0:8080")
while True:
# 클라이언트 연결 대기
client_socket, address = server_socket.accept()
print(f"클라이언트 접속: {address}")
try:
# 데이터 수신
data = client_socket.recv(1024)
if data:
print(f"수신 데이터: {data.decode()}")
# 데이터 송신
response = f"에코: {data.decode()}"
client_socket.send(response.encode())
finally:
# 연결 종료
client_socket.close()
if __name__ == "__main__":
tcp_server()🎯 예시 2: UDP 서버 구현 (Python)
import socket
def udp_server():
# 소켓 생성
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', 9090))
print("UDP 서버 시작: 0.0.0.0:9090")
while True:
# 데이터 수신
data, address = server_socket.recvfrom(1024)
print(f"수신 데이터: {data.decode()} (from {address})")
# 데이터 송신
response = f"에코: {data.decode()}"
server_socket.sendto(response.encode(), address)
if __name__ == "__main__":
udp_server()🎯 예시 3: TCP 클라이언트 구현 (Python)
import socket
def tcp_client(server_ip, server_port):
# 소켓 생성
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 서버 연결
client_socket.connect((server_ip, server_port))
print(f"서버 연결 성공: {server_ip}:{server_port}")
# 데이터 송신
message = "Hello, Server!"
client_socket.send(message.encode())
# 데이터 수신
data = client_socket.recv(1024)
print(f"서버 응답: {data.decode()}")
finally:
# 연결 종료
client_socket.close()
if __name__ == "__main__":
tcp_client('192.168.1.100', 8080)Part 10: 실무 문제 및 해결
🎯 문제 1: TCP 연결 시간이 너무 느림
상황: TCP 3-way Handshake가 느리게 진행됨
원인:
- 네트워크 지연 (latency) 높음
- 패킷 손실이 발생하여 재전송
- 혼잡 상태로 네트워크 포화됨
해결 방법:
- 네트워크 최적화: 더 가까운 서버 이용, CDN 활용
- TCP 파라미터 튜닝: 혼잡 제어 알고리즘 조정
- HTTP/2, HTTP/3: 멀티플렉싱 활용으로 병렬 전송
🎯 문제 2: 실시간 애플리케이션 데이터 끊김 현상
상황: 온라인 게임에서 캐릭터가 끊겨서 이동 현상 발생
원인: UDP 패킷 손실로 인한 데이터 누�
해결 방법:
- UDP 재전송 구현: 애플리케이 레벨에서 재전송
- 부분 중복 전송: 동일 데이터를 여러 번 전송
- 예측 전송: 클라이언트에서 다음 위치 예측하여 미리 전송
Part 11: 학습자 스스로 체크 포인트
📝 자기 평가 질문
-
TCP와 UDP의 차이점을 설명할 수 있나요?
- 💡 힌트: 택배 vs 우편 비유
-
3-way Handshake 과정을 설명할 수 있나요?
- 💡 힌트: SYN → SYN-ACK → ACK
-
순서 번호(Sequence Number)의 역할을 설명할 수 있나요?
- 💡 힌트: 데이터 순서 식별
-
흐름 제어(Flow Control)와 혼잡 제어(Congestion Control)의 차이를 설명할 수 있나요?
- 💡 힌트: 수신측 능력 vs 네트워크 상태
-
포트 번호와 소켓의 관계를 설명할 수 있나요?
- 💡 힌트: IP 주소 + 포트 번호
Part 12: 실무 명령어
# 1. 포트 확인
netstat -an | grep LISTEN
ss -tuln
# 2. TCP 연결 상태 확인
netstat -an | grep ESTABLISHED
# 3. 포트 스캔
nmap -sV localhost
# 4. TCP 연결 테스트
telnet example.com 80
nc -zv example.com 80
# 5. 서버 테스트
curl -I https://www.example.comPart 13: 다음 단계
📚 학습 경로
이 모드를 완료했다면 다음 모듈로 이동하세요:
추천 학습 순서:
- ✅ 모듈 1: 네트워크 기초와 OSI 모델 (완료)
- ✅ 모듈 2: IP 주소와 서브넷팅 (완료)
- ✅ 모듈 3: TCP와 UDP (현재)
- ⏭️ 모듈 4: DNS 동작 원리
- DNS 쿼리 과정
- DNS 레코드 설정
- DNS 레코드 운영
- ⏭️ 모듈 5: HTTP와 HTTPS
- HTTP 메서드와 상태 코드
- HTTPS 암호화 과정
🎓 학습 포인트 요약
✅ 이해해야 할 핵심 개념
- TCP vs UDP: 연결 지향 vs 비연결형, 신뢰성 vs 속도
- 3-way/4-way Handshake: 연결 설정/종료 과정
- 신뢰성 메커니즘: 순서 번호, ACK, 재전송, 타이머아웃
- 흐름 제어/혼잡 제어: 수신 측 능력, 네트워크 상태
- 포트 번호와 소켓: 애플리케이션 식별
💡 기억해야 할 공식
호스트 수 계산: 2^(32 - 마스크 비트) - 2
TCP 헤더 최소: 20바이트
UDP 헤더 고정: 8바이트
🎯 스스로 점검할 수 있는 능력
- TCP vs UDP 적절한 선택
- 혼잡 발생 시 대응 방안
- 포트 충돌 방지
- 실무에서 소켓 프로그래밍
🔗 관련 자료
📚 추천 학습 자료
-
교재
- “TCP/IP Illustrated” - W. Richard Stevens
- “Computer Networking: A Top-Down Approach” - James Kurose, Keith Ross
-
온라인
-
실습 도구
다음 모듈: DNS 동작 원리 학습