본문 바로가기
네트워크

[네트워크] 전송 계층: TCP, UDP

by Bokoo14 2025. 1. 28.

전송 계층에서 가장 중요한 프로토콜: TCP, UDP

목적과 특징

포트를 통한 프로세스 식별

IP주소와 MAC주소는 패킷을 송수신하는 호스트를 특정할 수 있음

패킷은 호스트가 실행하는 프로세스에 송수신해야 함

하나의 호스트는 다양한 프로세스를 동시에 실행할 수 있어서, 네트워크 상의 호스트가 실행하는 프로세스를 식별해야 함

포트(port) 번호로 프로세스를 식별할 수 있음

IP 주소와 포트 번호의 조합으로 '특정 호스트가 실행하는 특정 프로세스'를 식별할 수 있다.

"IP 주소: 포트 번호"

 

TCP와 UDP 모두 포트를 통해 프로세스 식별

 

16비트로 표현할 수 있는 포트 번호는 총 2**16개 = 65536개

포트 종류 포트 번호 범위  
잘 알려진 포트 (well knwon port) 0 ~ 1023 범용적으로 사용되는 프로토콜
등록된 포트 (registered port) 1024 ~ 49151 흔하게 사용되는 애플리케이션 프로토콜
동적 포트 (dynamic port) 49152 ~ 65535 비교적 자유롭게 사용 가능한 포트 번호
클라이언트로서 동작하는 프로그램의 경우에는 동적 포트 번호 중 임의의 번호가 할당되는 경우도 많음

 


NAT, NAPT

NAT (Network Address Translation)

공인 IP 주소와 사설 IP 주소 간 변환

네트워크 내부에서 사설 IP 주소를 사용하는 호스트가 네트워크 외부에 있는 호스트와 패킷을 주고받기 위해서 공인 IP 주소와 사설 IP 주소 간 변환이 필요함

변환하고자하는 IP 주소를 일대일 대응하지 않고, 다수의 사설 IP 주소를 그보다 적은 수의 공인 IP 주소로 변환

사설 IP 주소를 사용하는 여러 호스트가 적은 수의 공인 IP 주소를 공유

NAPT (Network Address Port Translation)

포트 번호도 함께 고려하는 포트 기반의 NAT

IP 주소 쌍과 함께 포트 번호도 함께 기록하고 변환하여 하나의 공인 IP 주소를 여러 사설 IP 주소가 공유할 수 있도록 하는 NAT의 일종


 

TCP

신뢰할 수 있는 연결형 송수신

패킷을 주고받기 전에 연결 수립 과정을 거치며, 연결 수립 이후 패킷을 주고받을 때 신뢰성 보장을 위해 상태 관리, 흐름 제어, 오류 제어, 혼잡 제어 등의 각종 기능 제공

TCP 헤더

  • 송신지 포트: 송신 프로세스가 할당된 포트 번호
  • 수신지 포트: 수신 프로세스가 할당된 포트 번호
  • 길이 필드: 헤더를 포함한 UDP 패킷의 바이트 크기
  • 체크섬 필드: 송수신 과정에서의 데이터그램 훼손 여부를 알 수 있는 정보
  • 순서 번호 필드 (sequence number)
    • TCP 패킷(TCP 세그먼트)의 올바른 송수신 순서를 보장하기 위해 세그먼트 첫 바이트에 매겨진 번호
    • 현재 주고받는 TCP 세그먼트가 송수신하고자 하는 데이터의 몇 번째 바이트에 해당하는지 알 수 있음
  • 확인 응답 번호 필드 (acknowledgment number)
    • 상대 호스트가 보낸 세그먼트에 대한 응답
    • 다음으로 수신하길 기대하는 순서 번호
    • 일반적으로 '올바르게 수신한 순서 번호에 1이 더해진 값'으로 설정
  • 일부 제어 비트 (ACK 플래그, SYN 플래그, FIN 플래그)
    • 현재 세그먼트에 대한 부가 정보를 나타내는 정보
    • 기본적으로 8비트로 구성
    • ACK: 세그먼트의 승인을 나타내기 위한 비트
    • SYN: 연결을 수립하기 위한 비트
    • FIN: 연결을 종료하기 위한 비트

UDP

신뢰할 수 없는 비연결형 송수신

연결의 수립이나 종료 단계를 거치지 않고, 신뢰성을 높이기 위한 기능 제공하지 않음

UDP 헤더

  • 송신지 포트: 송신 프로세스가 할당된 포트 번호
  • 수신지 포트: 수신 프로세스가 할당된 포트 번호
  • 길이 필드: 헤더를 포함한 UDP 패킷의 바이트 크기
  • 체크섬 필드: 송수신 과정에서의 데이터그램 훼손 여부를 알 수 있는 정보

 

일반적으로 TCP가 UDP에 비해 송수신 속도가 느림
패킷의 유실 없는 송수신을 원한다면 TCP
비교적 빠른 송수신을 원한다면 UDP

TCP의 연결부터 종료까지

TCP는 송수신 이전에 연결을 수립하고, 송수신 이후에 연결을 종료

송수신 전후로 '상태'라는 값을 관리


TCP 연결

TCP의 연결 수립은 쓰리 웨이 핸드쉐이크(three way hand shake)를 통해 이루어짐

쓰리 웨이 핸드 쉐이크는 세 단계로 이루어진 TCP의 연결 수립 과정을 뜻함

1단계: 클라이언트 -> 서버 (SYN)

  • 클라이언트는 서버에 연결 요청을 보내기 위해 SYN(Synchronize) 플래그가 설정된 세그먼트를 전송
  • 이 세그먼트에는 초기 시퀀스 번호(ISN, Initial Sequence Number)가 포함
  • 이 단계는 "연결을 시작할 준비가 되었다"라는 신호
  • 예시) 클라이언트가 "서버야, 연결할 준비가 되었어. 내 초기 번호는 1000이야!"라고 신호를 보낸다고 이해할 수 있다

2단계: 서버 -> 클라이언트 (SYN + ACK)

  • 서버는 클라이언트의 요청을 수락하면서 SYN 플래그와 ACK(Acknowledgment) 플래그가 설정된 세그먼트를 전송
  • 이 때 서버는 클라이언트의 ISN에 +1을 하여 ACK로 응답하고, 자신의 초기 시퀀스 번호(ISN)도 함께 보낸다.
  • 예시) 서버가 "좋아, 요청 확인했어(ACK: 1001). 내 초기 번호는 2000이야(SYN)"라고 신호를 보내는 것

3단계: 클라이언트 -> 서버 (ACK)

  • 클라이언트는 서버의 응답을 확인하고, 서버의 초기 시퀀스 번호(ISN)에 +1을 한 ACK 세그먼트를 서버로 전송
  • 이 단계가 완료되면 TCP 연결이 수립되며 데이터 전송이 시작될 수 있다
  • 예시) 클라이언트가 "서버야, 너의 초기 번호 2000 확인했어. 다음은 2001이야!"라고 신호를 보내는 것

 

액티브 오픈 (Active Open)

  • 연결을 요청하는 측(클라이언트)가 액티브 오픈을 수행
  • 클라이언트는 서버에 연결 요청을 보내기 위해 SYN 패킷을 전송
  • 예시)
    • 사용자가 웹 브라우저를 열고 특정 URL에 접속할 때, 브라우저(클라이언트)는 해당 웹 서버에 연결 요청을 보낸다.
    • 이때 클라이언트가 액티브 오픈 역할

패시브 오픈 (Passive Open)

  • 연결 요청을 대기하는 측(서버)가 패시브 오픈을 수행
  • 서버는 미리 포트를 열어두고(바인딩) 클라이언트의 요청을 기다린다.
  • 예시)
    • 웹 서버는 항상 특정 포트(예: 80번 포트)에서 연결 요청을 기다린다.
    • 이때 서버가 패시브 오픈 역할

TCP의 오류, 흐름, 혼잡 제어

TCP는 송수신하는 패킷의 신뢰성을 보장하기 위해 3가지 기능(오류 제어, 흐름 제어, 혼잡 제어)을 제공

재전송을 통한 오류 제어

송수신 과정에서 잘못된 세그먼트가 있을 경우, 이를 재전송하여 오류를 제어

중복된 ACK 세그먼트가 도착했을 때, 타임아웃이 발생했을 때 잘못 전송된 세그먼트가 있음을 인지함

  • 중복된 ACK 세그먼트가 도착했을 때
    • 송신한 세그먼트의 일부가 전송 중 유실되어 중복으로 ACK 세그먼트를 수신하는 상황
  • 타임아웃(timeout)이 발생했을 때
    • 재전송 타이머(retransmission timer)의 카운트다운이 끝난 상황

참고: 파이프라이닝 전송 (pipelining)

한 번에 여러 세그먼트를 보내어 확인 응답을 받기 전이라도 여러 메시지를 보내는 방식으로 송신

흐름 제어 (flow control)

수신 호스트가 한 번에 n개의 바이트를 받아 처리할 수 있다면 송신 호스트는 n 바이트 이상을 보낼 수 있어도 n 바이트를 넘지 않는 선에서 송신해야 함

수신 호스트가 한 번에 받아 처리할 수 있을 만큼만 전송하는 것

수신 호스트가 한 번에 받을 수 있는 전송량은 TCP 수신 버퍼의 크기에 의해 결정됨

 

수신 윈도우 (receiver window): 수신 호스트가 한 번에 처리할 수 있는 양

 

수신 호스트는 윈도우 필드를 통해 송신 호스트에게 한 번에 처리 가능한 양을 알려주고, 송신 호스트는 전달받은 해당 값을 토대로 세그먼트를 전송

혼잡 제어 (congestion control)

혼잡: 많은 트래픽으로 인해 패킷의 처리 속도가 느려지거나 유실될 수 있는 상황

혼잡 제어의 주체는 송신 호스트

네트워크 혼잡 여부 판단 기준: 중복된 ACK 세그먼트가 도착했을 떄, 타임아웃이 발생했을 때 현재 네트워크가 혼잡하다고 판단

 

혼잡 가능성을 검출한 송신 호스트는 혼잡없이 전송할 수 있을 정도의 양(혼잡 윈도우(congestion window))만큼만 송신

호스트는 각자 혼잡 윈도우 값을 고려하여 혼잡 윈도우 값을 넘지 않는 선에서 전송

 

흐름 제어에서 사용되는 수신 윈도우와 혼잡 제어에서 사용되는 혼잡 윈도우는 모두 커널 내에서 정의된 값

 

수신 윈도우 크기: 수신 호스트가 TCP 헤더로 알려줌

혼잡 윈도우 크기: 송신 호스트가 직접 계산하여 알아내야 함

 

혼잡 제어 알고리즘 (congestion control algorithm)

혼잡 윈도우 크기를 연산하는 방법

AIMD(Additive increase/Multiplicative Decrease): 합으로 증가, 곱으로 감소

세그먼트를 보내고, 그에 대한 응답이 오기까지 혼잡이 감지되지 않으면 혼잡 윈도우를 1씩 선형적으로 증가, 혼잡이 감지되면 혼잡 윈도우를 절반으로 떨어트리는 동작을 반복하는 알고리즘

  • RTT(round trip time): 패킷을 보내고 그에 대한 응답이 수신되기까지의 시간

AIMD는 혼잡이 감지되지 않으면 혼잡 윈도우를 RTT마다 1씩 선형적으로 증가시키고, 혼잡이 감지되면 혼잡 윈도우를 절반으로 떨어트림


TCP의 종료

TCP의 연결 종료는 포 웨이 핸드쉐이크 (Four-Way Handshake)를 통해 이루어짐
포 웨이 핸드쉐이크는 송수신 호스트가 각자 FINACK 세그먼트를 주고받으며 연결을 종료하는 네 단계로 구성됨

1단계: 클라이언트 -> 서버 (FIN)

클라이언트는 더 이상 보낼 데이터가 없음을 서버에 알리기 위해 FIN 플래그가 설정된 세그먼트를 전송

  • 이 단계는 클라이언트가 "더 이상 보낼 데이터가 없어, 연결을 닫을 준비를 할게!"라고 신호를 보내는 것
  • 이후 클라이언트는 반닫힘(half-closed) 상태가 됨

2단계: 서버 -> 클라이언트 (ACK)

서버는 클라이언트의 FIN 요청을 수락하고 ACK 플래그가 설정된 세그먼트를 전송

  • 이 때 서버는 연결 닫기 요청을 확인했다는 의미로 "알겠어, 요청 확인했어!"라고 응답하는 것
  • 서버는 여전히 데이터를 전송할 수 있는 상태를 유지함

3단계: 서버 -> 클라이언트 (FIN)

서버는 더 이상 보낼 데이터가 없을 때 클라이언트에게 FIN 플래그가 설정된 세그먼트를 전송

  • 이 단계는 서버가 "나도 보낼 데이터가 없어. 이제 연결 닫자!"라고 신호를 보내는 것

4단계: 클라이언트 -> 서버 (ACK)

클라이언트는 서버의 FIN 요청을 확인하고 ACK 플래그가 설정된 세그먼트를 전송

  • 이 단계가 완료되면 양쪽 연결이 완전히 종료됨
  • 클라이언트는 "확인했어! 이제 연결 닫아도 돼!"라고 응답하는 것

 

액티브 종료 (Active Close)

연결 종료를 먼저 요청하는 측(보통 클라이언트)이 FIN 패킷을 전송

  • 예시) 웹 브라우저에서 페이지 로드가 끝나면 클라이언트가 연결 종료 요청을 먼저 보냄

패시브 종료 (Passive Close)

연결 종료 요청을 수락하는 측(보통 서버)이 FIN 패킷에 응답

  • 예시) 웹 서버는 클라이언트가 연결 종료 요청을 보내면 이를 수락하고 연결을 닫음

TCP 상태 관리

TCP는 상태를 유지하고 관리하는 프로토콜이라는 점에서 스테이트풀 프로토콜(stateful protocol)이라고도 부름

상태(state): 현재 어떤 통신 과정에 있는지를 나타내는 정보

연결이 수립되지 않았을 때

  • CLOSED: 아무런 연결이 없는 상태
  • LISTEN: 연결 대기 상태 (쓰리 웨이 핸드쉐이크의 첫 단계인 SYN 세그먼트를 대기하는 상태)

연결 수립 과정

  • SYN-SENT: 액티브 오픈 호스트가 SYN 세그먼트를 보낸 뒤 그에 대한 응답인 SYN+ACK 세그먼트를 기다리는 상태 (연결 요청 전송)
  • SYN-RECIEVED: 패시브 오픈 호스트가 ACK+ACK 세그먼트를 보낸 뒤 그에 대한 ACK 세그먼트를 기다리는 상태 (연결 요청 수신)
  • ESTABLISHED: 쓰리 웨이 핸드쉐이크가 끝난 뒹 데이터를 송수신할 수 있는 상태 (연결 수립)

연결 종료 과정

  • FIN-WAIT-1: 액티브 클로즈 호스트가 FIN 세그먼트로 연결 종료 요청을 보낸 상태 (연결 종료 요청 전송)
  • CLOSE-WAIT: FIN 세그먼트를 받은 패시브 클로즈 호스트가 그에 대한 응답으로 ACK 세그먼트를 보낸 후 대기하는 상태 (연결 종료 요청 승인)
  • FIN-WAIT-2: FIN-WAIT-1 상태에서 ACK 세그먼트를 받은 상태
  • LAST-ACK: CLOSE-WAIT 상태에서 FIN 세그먼트를 전송한 뒤 대기하는 상태
  • TIME-WAIT: 액티브 클로즈 호스트가 마지막 ACK 세그먼트를 전송한 뒤 접어드는 상태

패시브 클로즈 호스트가 마지막 ACK 세그먼트를 수신하면 CLOSE 상태가 됨

TIME-WAIT 상태에 접어든 액티브 클로즈 호스트는 일정 시간을 기다린 뒤 CLOSED 상태가 된다.

마지막 ACK 세그먼트가 올바르게 전송되지 않으면 재전송이 필요하기 때문