TCP·UDP와 연결·순서 제어
대표 포트, TCP 연결과 종료, Seq/Ack 계산 및 흐름·혼잡 제어를 학습합니다.
TCP·UDP는 포트로 응용의 통신 종단을 구분한다. TCP는 연결 지향의 신뢰성 있는 순서화 바이트 스트림이며, 손실 데이터의 재전송과 누적 ACK를 사용한다. 응용이 보낸 메시지의 경계를 그대로 보존하지 않는다. UDP는 데이터그램의 경계를 유지하지만 자체적으로 전달·순서를 보장하지 않는다.
1. 포트 번호의 범위
TCP와 UDP의 포트 번호는 각각 16비트이므로 0~65535 범위를 가진다. IANA는 관리 관점에서 세 구간으로 나눈다.
| 구간 | 범위 | 의미 |
|---|---|---|
| System Ports | 0~1023 | 전통적으로 Well-Known Ports라고 부르는 시스템 서비스 영역 |
| User Ports | 1024~49151 | 전통적으로 Registered Ports라고 부르는 등록 가능 영역 |
| Dynamic/Private Ports | 49152~65535 | IANA가 개별 서비스에 할당하지 않는 동적·사설 영역 |
포트 0은 TCP와 UDP 모두 Reserved로 등록되어 있다.
클라이언트가 서버에 접속할 때 운영체제는 보통 임시 출발지 포트(ephemeral port)를 선택한다. 다만 실제 운영체제가 사용하는 ephemeral port 범위가 반드시 IANA의 Dynamic/Private 범위와 정확히 같다고 단정하면 안 된다. 운영체제와 설정에 따라 선택 범위가 달라질 수 있다.
또한 등록된 포트 번호는 그 트래픽의 실제 응용 프로그램을 보증하지 않는다. 예를 들어 목적지 포트가 특정 서비스에 등록되어 있어도 다른 프로그램이 그 포트를 사용할 수 있다. 보안 분석에서는 포트 번호만 보고 정상 서비스라고 확정하지 않고 패킷 내용·프로세스·로그를 함께 본다.
2. 대표 포트는 ‘숫자 + 전송 프로토콜’을 함께 본다
대표적으로 다음 포트가 자주 등장한다.
| 서비스 | 대표 포트/전송 | 핵심 구분 |
|---|---|---|
| FTP 제어 | TCP 21 | 명령·제어 연결 |
| FTP 데이터 | TCP 20 | 전통적 active mode의 서버 데이터 포트 |
| SSH | TCP 22 | 보안 원격 접속 |
| Telnet | TCP 23 | 평문 원격 터미널 |
| SMTP | TCP 25 | 메일 전송 |
| DNS | UDP 53 / TCP 53 | UDP와 TCP 모두 사용 가능 |
| DHCP | UDP 67 / UDP 68 | 서버 67, 클라이언트 68 |
| HTTP | TCP 80 | 전통적 HTTP 전송 |
| POP3 | TCP 110 | 메일 수신 프로토콜 |
| IMAP | TCP 143 | 메일함 동기화·접근 |
| SNMP | UDP 161 / 162 | 요청·응답 161, Trap/Inform 관련 162가 대표적 |
| HTTPS | TCP 443이 대표적 | 현대에는 UDP 443을 사용하는 전송도 있으므로 443=항상 TCP로 일반화하지 않는다 |
시험에서는 대표 포트를 기억하되 다음처럼 해석하는 습관이 중요하다.
22라는 숫자만 보는 것보다 → TCP/22인가?
53이라는 숫자만 보는 것보다 → UDP/53인가, TCP/53인가?
443이라는 숫자만 보는 것보다 → TCP인가 UDP인가, 실제 페이로드는 무엇인가?
3. UDP: 작은 헤더의 비연결형 데이터그램 전송
UDP는 데이터를 데이터그램(datagram) 단위로 전달한다. 전송 전에 TCP와 같은 연결 설정 절차를 수행하지 않는다.
UDP 자체가 제공하지 않는 기능을 분명히 구분해야 한다.
- 데이터 도착 보장 없음
- 중복 방지 보장 없음
- 순서 보장 없음
- 손실 시 UDP 계층 자체의 재전송 없음
- UDP 계층 자체의 흐름 제어 없음
- UDP 계층 자체의 혼잡 제어 없음
이 말이 “UDP를 사용하는 응용 프로그램은 신뢰성이나 혼잡 제어를 구현할 수 없다”는 뜻은 아니다. 필요하면 상위 응용 프로토콜이 별도의 확인·재전송·순서·혼잡 제어 기능을 설계할 수 있다. 따라서 단순히 UDP는 항상 빠르고 TCP는 항상 느리다고 외우는 것은 정확하지 않다. UDP는 프로토콜 자체의 연결·재전송 상태가 단순하지만 실제 성능은 응용 설계와 네트워크 상황에 따라 달라진다.
UDP 헤더
기본 UDP 헤더는 8바이트이며 네 개의 16비트 필드로 구성된다.
Source Port 16비트
Destination Port 16비트
Length 16비트
Checksum 16비트
Length에는 UDP 헤더와 데이터 전체 길이가 포함되므로 일반 UDP의 최소 길이는 8바이트다.
UDP 체크섬은 전송 오류를 검출하기 위한 값이지 암호화·인증 기능이 아니다. IPv4에서는 체크섬 0이 “체크섬을 생성하지 않음”을 나타낼 수 있지만, IPv6에서는 기본적으로 UDP 체크섬을 계산해야 하며 특수한 터널링 예외만 별도 규칙을 따른다.
UDP는 메시지 경계를 유지한다
응용 프로그램이 UDP 데이터그램 A와 B를 별도로 보냈다면 수신 측 UDP에도 각각 데이터그램 단위로 전달된다. 도착 자체나 순서는 보장하지 않지만 데이터그램의 메시지 경계는 TCP의 바이트 스트림과 다르다.
4. TCP 헤더에서 우선 해석할 필드
TCP 기본 헤더는 옵션이 없을 때 20바이트다. Data Offset 필드가 TCP 헤더 길이를 32비트 단위로 나타내며 옵션이 붙으면 더 길어질 수 있다.
| 필드 | 시험에서의 핵심 의미 |
|---|---|
| Source Port / Destination Port | 송수신 프로세스 식별 |
| Sequence Number | 이 세그먼트에서 시작하는 바이트의 순서 위치 |
| Acknowledgment Number | 수신자가 다음에 기대하는 Sequence Number |
| Data Offset | TCP 헤더 길이 |
| Window | 상대방에게 광고하는 수신 가능 범위(rwnd) |
| Checksum | TCP 헤더·데이터 및 IP 의사 헤더를 포함한 오류 검출 |
| Urgent Pointer | URG가 설정될 때 긴급 데이터 위치 관련 정보 |
| Options | MSS, Window Scale, SACK Permitted, Timestamp 등 확장 정보가 들어갈 수 있음 |
TCP 플래그
시험 문제에서는 다음 여섯 개가 특히 자주 등장한다.
| 플래그 | 의미 |
|---|---|
| URG | Urgent Pointer가 유효함을 표시 |
| ACK | Acknowledgment 필드가 유효함을 표시 |
| PSH | Push 기능을 요청 |
| RST | 연결을 재설정(reset) |
| SYN | 연결 수립 시 Sequence Number를 동기화 |
| FIN | 송신자가 더 보낼 데이터가 없음을 알림 |
현행 TCP 헤더에는 이 여섯 개 외에도 ECN과 관련된 ECE, CWR 제어 비트가 할당되어 있다. 따라서 “TCP 헤더에는 플래그가 정확히 6개뿐이다”라고 일반화하지 않는다. 다만 연결 수립·종료와 일반적인 필기 문제에서는 URG/ACK/PSH/RST/SYN/FIN이 핵심이다.
PSH=1을 “수신 응용 프로그램이 무조건 즉시 읽도록 강제한다”로 외우는 것도 과도한 단순화다. PSH는 TCP의 Push 기능과 관련된 신호이지 응용 프로그램의 스케줄링까지 강제하는 명령은 아니다.
5. Sequence Number와 ACK Number는 ‘패킷 번호’가 아니라 바이트 위치다
TCP Sequence Number는 일반적으로 바이트 스트림의 위치를 나타낸다.
예를 들어 수신자가 다음을 받았다고 하자.
Sequence Number = 1001
Data Length = 100 bytes
오류 없이 100바이트를 연속해서 받았다면 다음에 기대하는 번호는 다음과 같다.
1001 + 100 = 1101
따라서 수신자가 보내는 누적 ACK는 다음과 같이 해석할 수 있다.
ACK Number = 1101
의미: 1100번 바이트까지 연속으로 받았고 다음에는 1101번을 기대한다.
TCP의 ACK 필드를 “내가 마지막으로 받은 번호”라고 외우면 1 차이 오류가 발생하기 쉽다. ACK Number는 다음에 기대하는 번호라는 점을 기준으로 계산한다.
6. SYN과 FIN은 Sequence Number 공간을 1씩 사용한다
TCP에서는 연결 수립과 종료에 사용되는 SYN과 FIN도 Sequence Number 공간을 1씩 소비한다. 반면 데이터가 없는 일반 ACK만으로는 Sequence Number 공간을 추가 소비하지 않는다.
클라이언트의 초기 Sequence Number가 1000이라면 첫 SYN은 다음처럼 계산한다.
Client → Server
SYN, Seq=1000
서버는 이 SYN을 확인했으므로 다음 번호를 기대한다.
Ack = 1001
이 원리를 모르면 3-way handshake의 ACK = ISN + 1 관계를 제대로 해석하기 어렵다.
7. TCP 3-way handshake
TCP의 대표적인 연결 수립은 다음 세 단계다.
1단계: SYN
클라이언트가 서버에 연결을 요청하면서 자신의 초기 Sequence Number(ISN)를 알린다.
Client → Server
SYN=1
Seq=1000
클라이언트는 일반적으로 SYN-SENT 상태가 된다.
2단계: SYN + ACK
서버가 연결 요청을 받아들이면 자신의 초기 Sequence Number를 보내면서 클라이언트의 SYN도 확인한다.
Server → Client
SYN=1, ACK=1
Seq=5000
Ack=1001
Ack=1001은 클라이언트의 SYN이 Sequence Number 1000을 사용했으므로 다음 번호 1001을 기대한다는 뜻이다.
3단계: ACK
클라이언트가 서버의 SYN을 확인한다.
Client → Server
ACK=1
Seq=1001
Ack=5001
정상적으로 완료되면 양쪽은 ESTABLISHED 상태에서 데이터를 주고받을 수 있다.
3-way handshake는 TCP 상태와 초기 Sequence Number를 동기화한다. 그러나 이 절차 자체가 상대방의 실제 신원을 암호학적으로 인증하는 것은 아니다. 신원 인증·기밀성·무결성이 필요하면 TLS, SSH, IPsec 같은 별도의 보안 메커니즘이 필요하다.
8. 흐름 제어와 혼잡 제어를 구분한다
두 기능은 모두 “너무 많이 보내지 않도록 조절한다”는 공통점이 있지만 기준이 다르다.
흐름 제어: 수신자의 버퍼를 넘치지 않게 한다
TCP 수신자는 헤더의 Window 값으로 자신이 추가로 받을 수 있는 데이터 범위를 광고한다. 이를 수신 윈도우(receiver window, rwnd)라고 한다.
rwnd가 작다 → 수신 측 처리 여유가 적음
rwnd가 크다 → 수신 측이 더 많은 미확인 데이터를 받을 여유가 있음
혼잡 제어: 네트워크 자체를 과부하시키지 않게 한다
송신 측은 네트워크 상태를 고려한 혼잡 윈도(cwnd)도 관리한다. 실제 송신 가능한 미확인 데이터량은 단순화하면 rwnd와 cwnd 중 더 작은 제한의 영향을 받는다.
예를 들어 다음과 같다고 하자.
rwnd = 24 KB
cwnd = 10 KB
수신자는 24KB를 받을 수 있어도 네트워크 혼잡 제어가 10KB만 허용한다면 송신자는 그 제한을 넘어 전송하지 않는다.
반대로 다음 상황에서는 수신 측이 병목이다.
rwnd = 24 KB
cwnd = 64 KB
이 경우에는 수신자가 광고한 24KB가 더 작은 제한이다.
따라서 다음처럼 구분한다.
Flow Control → Receiver 상태 중심 → rwnd
Congestion Control → Network 상태 중심 → cwnd
9. TCP 연결 종료는 양방향을 독립적으로 닫는다
TCP는 전이중 통신이므로 한쪽 방향의 전송을 끝내는 것과 반대 방향의 전송을 끝내는 것을 독립적으로 처리할 수 있다.
대표적인 정상 종료를 클라이언트가 먼저 시작한다고 하자.
- 클라이언트가
FIN을 보내고FIN-WAIT-1로 이동한다. - 서버가 FIN을 ACK하고
CLOSE-WAIT가 된다. 클라이언트는 ACK를 받으면FIN-WAIT-2로 이동한다. - 서버 응용 프로그램도 종료를 요청하면 서버가 자신의
FIN을 보낸다. - 클라이언트가 서버의 FIN을 ACK하고 일반적인 active closer로서
TIME-WAIT상태에 들어간다. - 서버는 자신의 FIN에 대한 ACK를 받으면 연결을 닫는다.
- active closer는 TIME-WAIT 조건을 만족한 뒤
CLOSED로 전환한다.
이 흐름은 흔히 네 개의 FIN/ACK 세그먼트로 표현하지만 항상 정확히 네 패킷이어야 하는 것은 아니다. ACK와 자신의 FIN을 같은 세그먼트에 함께 실을 수도 있고 양쪽이 동시에 종료할 수도 있다.
TIME-WAIT
정상적인 active close를 수행한 TCP는 대표적으로 TIME-WAIT 상태를 거친다. 이 상태는 지연되어 도착한 과거 세그먼트가 새로운 연결과 혼동되는 것을 줄이고, 상대가 마지막 ACK를 받지 못해 FIN을 재전송했을 때 다시 ACK할 수 있게 한다.
TIME-WAIT은 “항상 클라이언트 상태”가 아니다. 먼저 active close를 수행한 쪽에서 나타나는 것이 일반적이다. 서버가 먼저 종료하면 서버 쪽에서도 발생할 수 있다.
RST는 정상 FIN 종료와 다르다
RST는 정상적인 양방향 FIN 교환과 달리 연결을 재설정하거나 비정상적으로 중단할 때 사용된다. 패킷 분석에서는 다음처럼 구분한다.
SYN → 연결 수립 시도
SYN + ACK → 연결 요청 수락·응답
FIN + ACK → 정상 종료 방향의 진행
RST → 연결 재설정·거부·비정상 중단 가능성
RST 하나만 보고 공격이라고 단정해서도 안 된다. 닫힌 포트, 존재하지 않는 연결, 응용 프로그램의 강제 종료 등 정상적인 운영 상황에서도 RST가 나타날 수 있다.
10. TCP의 주요 상태를 흐름으로 읽는다
모든 상태 전이를 통째로 암기하기보다 연결의 어느 단계인지 구분한다.
| 상태 | 의미 |
|---|---|
| CLOSED | 연결 없음 |
| LISTEN | 서버가 연결 요청을 기다림 |
| SYN-SENT | 능동적으로 SYN을 보내고 응답을 기다림 |
| SYN-RECEIVED | SYN을 받고 SYN+ACK 후 최종 ACK를 기다림 |
| ESTABLISHED | 연결 수립 완료, 데이터 송수신 가능 |
| FIN-WAIT-1 | 내가 FIN을 보내고 ACK/상대 FIN을 기다림 |
| FIN-WAIT-2 | 내 FIN은 ACK되었고 상대 FIN을 기다림 |
| CLOSE-WAIT | 상대 FIN을 받았고 로컬 응용 프로그램의 종료를 기다림 |
| LAST-ACK | 상대 FIN을 받은 뒤 내 FIN도 보냈고 마지막 ACK를 기다림 |
| CLOSING | 양쪽 FIN이 교차한 동시 종료 상황 등에서 사용 |
| TIME-WAIT | active close 뒤 지연 세그먼트·마지막 ACK 재전송 가능성을 처리 |
상태를 패킷과 함께 읽으면 다음 관계가 보인다.
SYN-SENT가 오래 지속 → SYN에 대한 응답이 오지 않는 상황을 의심
CLOSE-WAIT가 과도하게 누적 → 원격 FIN은 받았지만 로컬 응용이 close하지 못하는 상황을 의심
TIME-WAIT가 존재 → 정상적인 active close 뒤에도 나타날 수 있으므로 곧바로 장애로 판단하지 않음
이러한 상태 해석은 뒤의 netstat·패킷 분석·SYN Flooding 학습으로 연결된다.
개념 확인 문제
문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.
01Seq=1001에서 연속된 데이터 100바이트를 받았다면 다음 누적 ACK는?
1101이다. ACK는 마지막으로 받은 바이트 번호가 아니라 다음에 기대하는 바이트 번호다.
02흐름 제어와 혼잡 제어의 기준은 각각 무엇인가?
흐름 제어는 수신자의 처리·버퍼 여유(rwnd), 혼잡 제어는 네트워크 상태(cwnd)를 기준으로 전송량을 제한한다.