1. TCP vs UDP, 게임에서의 선택, 3-way handshake
난이도 하내 답안
모범답안
모범답안 — TCP vs UDP, 게임에서의 선택, 3-way handshake
난이도: 하
핵심 답변
- TCP: 연결 지향, 신뢰성(유실 시 재전송), 순서 보장, 흐름·혼잡 제어를 제공하는 바이트 스트림. 대신 핸드셰이크/ACK/재전송 때문에 지연(latency)과 오버헤드가 있고, 한 패킷이 막히면 뒤따르는 데이터가 모두 막히는 HOL(Head-of-Line) blocking이 발생한다.
- UDP: 비연결, 신뢰성·순서·흐름제어 없음. 단순히 데이터그램을 던진다. 그래서 빠르고 오버헤드가 작지만, 유실·중복·순서뒤바뀜은 애플리케이션이 직접 감당해야 한다.
- 게임에서는 "틀려도 되니 빨라야 하는 데이터는 UDP, 절대 틀리면 안 되는 데이터는 TCP" 가 큰 원칙이다.
깊이 있는 설명
| 항목 | TCP | UDP |
|---|---|---|
| 연결 | 연결 지향(handshake) | 비연결 |
| 신뢰성 | 보장(ACK + 재전송) | 없음 |
| 순서 | 보장(시퀀스 번호) | 없음 |
| 경계 | 없음(바이트 스트림) | 있음(데이터그램 단위) |
| 흐름/혼잡 제어 | 있음 | 없음 |
| 헤더 크기 | 20바이트~ | 8바이트 |
| HOL blocking | 발생 | 없음(독립 데이터그램) |
게임의 실시간성에서 TCP의 가장 큰 적은 재전송으로 인한 지연과 HOL blocking이다. 예를 들어 1초 전 위치 패킷이 유실되어 재전송되는 동안, 이미 도착한 "현재 위치"가 TCP 버퍼에서 순서를 기다리며 막힌다. 게임에서는 오래된 위치는 버리고 최신 위치만 쓰면 되는데, TCP는 그걸 못 한다(순서를 강제하므로). 이것이 실시간 게임이 UDP를 선호하는 핵심 이유다.
3-way handshake (연결 수립):
- SYN: 클라이언트가
SYN플래그 + 초기 시퀀스 번호(ISN, 예:seq=x)를 보낸다. → "연결하고 싶다, 내 시작 번호는 x" - SYN-ACK: 서버가
SYN+ACK, 자신의seq=y와ack=x+1을 보낸다. → "좋다(내 시작은 y), 네 x는 잘 받았으니 다음은 x+1" - ACK: 클라이언트가
ACK,ack=y+1을 보낸다. → "네 y도 받았다, 다음은 y+1"
이로써 양쪽이 서로의 시퀀스 번호를 교환·확인하고 송수신 준비가 끝난다. 핵심은 3번 왕복이 필요한 이유 = 양방향(full-duplex)이므로 각 방향의 초기 시퀀스 번호를 서로가 확인해야 하기 때문이다. (연결 종료는 4-way: FIN/ACK가 양방향 각각 필요.)
응용/실무 연결
- (a) 로그인/결제/거래 → TCP. 한 글자라도 틀리면 안 되고, 순서가 보장돼야 한다. 신뢰성은 절대값.
- (b) FPS 위치 동기화 → UDP. 60Hz로 위치를 쏘는데, 한두 개 유실돼도 다음 패킷이 곧 덮어쓴다. 최신성이 정확성보다 중요. TCP면 HOL blocking으로 렉이 체감된다.
- (c) 채팅 → 보통 TCP (유실/순서가 곤란하므로). 다만 대규모에서는 별도 채팅 서버 + TCP가 흔하다.
- (d) MMORPG 게임플레이 → 케이스 바이 케이스. 전통적 MMORPG는 TCP가 많다(스킬·거래·인벤토리 등 신뢰성이 중요하고 tick rate가 FPS보다 낮음). 액션성이 강하면 UDP+RUDP. 실제로는 TCP/UDP를 혼용(중요 데이터 TCP, 위치 UDP)하거나 신뢰성 UDP로 통합한다.
흔한 오답·함정
- "UDP는 무조건 빠르다" → 정확히는 오버헤드가 작고 재전송/순서대기가 없어 지연이 안정적인 것. 대역폭이 같으면 throughput 자체가 마법처럼 빠른 게 아니다.
- "UDP는 패킷 경계가 없다" → 틀림. UDP는 데이터그램 단위라 경계가 있다. 경계가 없는 건 TCP(스트림).
- "3-way handshake는 데이터 신뢰성 때문" → 정확히는 양방향 시퀀스 번호 동기화를 위한 것.
- "TCP를 쓰면 게임이 무조건 느리다" → 턴제·전략·낮은 tick 게임은 TCP가 멀쩡히 잘 동작한다. 도구는 요구사항에 맞춰 고른다.
꼬리질문 대비
- Q. UDP로 신뢰성이 필요한 패킷은 어떻게? A. 애플리케이션 레벨에서 시퀀스 번호 + ACK + 재전송을 구현한다(RUDP). 신뢰가 필요한 채널과 아닌 채널을 분리한다.
- Q. TCP의 HOL blocking을 피하려면? A. 독립 메시지는 UDP/RUDP로, 혹은 QUIC(UDP 기반, 스트림별 독립 전송)으로. TCP 내에서는 근본 해결 불가.
- Q. SYN flood 공격이 뭔가? A. SYN만 잔뜩 보내 서버의 half-open 연결 큐(백로그)를 고갈시키는 DoS. SYN cookie로 완화한다.
- Q. TIME_WAIT은 왜 있나? A. 종료 후 마지막 ACK 유실 대비 + 지연된 패킷이 새 연결에 섞이는 것 방지. 보통 2*MSL 유지.