[CS] 전송 계층 - TCP / UDP

눈치없어·2025년 3월 24일

네트워크 계층에서 가장 중요한 프로토콜이 IP라면 전송 계층에서 가장 중요한 프로토콜은 TCP와 UDP


TCP / UDP 목적과 특징

포트를 통한 프로세스 식별

  • IP 주소와 MAC 주소는 패킷을 송수신하는 호스트를 특정하지만, 실제로는 호스트가 실행하는 프로세스. 이를 식별하는 방법은 포트 번호
  • 네트워크 패킷을 주고받는 프로세스에는 포트 번호가 할당됨
  • IP 주소와 포트 번호의 조합으로 특정 호스트의 특정 프로세스를 식별할 수 있음

📌 TCP / UDP 역할

  • TCP와 UDP는 포트 번호를 통해 네트워크에서 송수신되는 프로세스를 식별
  • TCP와 UDP의 헤더에는 송신지 포트 번호와 수신지 포트 번호 필드가 포함하고 있음

📌 포트 번호의 종류

포트 번호는 개발자가 자주 다루는 정보 중 하나로 조금 더 자세히 알아 두는 것이 좋음

  • 16비트 포트 번호는 총 65536개로, 세 가지 종류로 나눠집니다
    - 잘 알려진 포트 0 ~ 1023 / 기본 프로토콜이 사용하는 포트
    - 등록된 포트 1024 ~ 49151번 / MySQL(3306) 등의 특정 애플리케이션에 할당된 포트
    - 동적 포트 49152 ~ 65535 / 사설 포트 or 임시 포트 라고도 불리는 동적포트

TCP와 UDP는 포트 번호를 사용하여 프로세스 식별
포트 번호는 잘 알려진 포트, 등록된 포트, 동적 포트로 구분되며, 각기 다른 용도에 따라 사용됨

📌 NAT와 NAPT

  • NAT (네트워크 주소 변환):
    - NAT는 사설 IP 주소와 공인 IP 주소 간의 변환을 담당하는 기술. 네트워크 내에서 사설 IP 주소를 사용하는 호스트가 외부와 통신하려면 공인 IP 주소가 필요
    - 대부분의 라우터나 공유기는 NAT 기능을 내장하고 있어, 네트워크 외부에서 패킷을 주고받을 때 사설 IP 주소를 공인 IP 주소로 변환하거나 반대로 변환하는 작업을 수행
  • NAPT (네트워크 주소 포트 변환):
    - NAPT는 NAT의 한 종류로, IP 주소 뿐만 아니라 포트 번호까지 변환. 이를 통해 여러 개의 사설 IP 주소가 하나의 공인 IP 주소를 공유하면서, 각 호스트를 포트 번호로 구별할 수 있음
    - 예를 들어, 웹 브라우저가 외부와 통신할 때 각 연결에 대해 동적 포트 번호가 할당됨. NAPT는 이를 통해 동일한 공인 IP 주소에서 여러 호스트가 동시에 인터넷과 통신할 수 있도록함

NAT는 사설 IP 주소와 공인 IP 주소 간의 변환을 수행하여, 내부 네트워크와 외부 네트워크 간의 통신을 가능하게함
NAPT는 포트 번호까지 포함하여 여러 사설 IP 주소가 하나의 공인 IP 주소를 공유할 수 있도록 도움


(비)신뢰성과 (비)연결형 보장

TCP는 신뢰할 수 있는 프로토콜이자 연결형 프로토콜이고, UDP는 신뢰할 수 없는 프로토콜이자 비연결형 프로토콜

  • 신뢰할 수 있는 연결형 송수신에는 시간과 연산이 소요되기 때문에 일반적으로 TCP가 UDP에 비해 송수신 속도가 느림
  • 패킷의 유실 없는 송수신을 원한다면 UDP보다 TCP를 선택하는 것이 유리하고 비교적 빠른 송수신을 원한다면 TCP보다 UDP를 선택하는 것이 유리함

📌 UDP 헤더

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

📌 TCP 헤더

  • TCP 헤더는 UDP보다 훨씬 더 많은 필드를 포함. TCP는 연결 수립 및 종료, 신뢰성 보장을 위해 여러 기능을 제공
    - 순서 번호: TCP 패킷의 올바른 송수신 순서를 보장하기 위해 세그먼트 첫 바이트에 매겨진 번호
    - 확인 응답 번호: 상대 호스트가 보낸 세그먼트에 대한 응답. 다음으로 수신하길 기대하는 순서 번호
    - 제어 비트: 현재 세그먼트에 대한 부가 정보를 나타내는 정보. 플래그 비트라고도 함

제어 비트 기본 3가지 종류

  • ACK: 세그먼트의 승인을 나타내기 위한 비트
  • SYN: 연결을 수립하기 위한 비트
  • FIN: 연결을 종료하기 위한 비트



TCP의 연결부터 종료까지

TCP는 UDP와 달리 송수신 이전에 연결을 수립하고, 송수신 이후에는 연결을 종료함
송수신 전후로 "상태"라는 값을 관리하기도 함

TCP의 연결 수립

TCP 연결 수립은 쓰리웨이 핸드셰이크(Three-way Handshake) 프로세스를 통해 이루어짐

1️⃣ [송수신 방향 A → B] SYN 세그먼트 전송
호스트 A는 SYN 비트가 1로 설정된 세그먼트를 호스트 B에게 전송
이때 세그먼트의 순서 번호에는 호스트 A의 순서 번호가 포함되어 있음

2️⃣ [송수신 방향 B → A] SYN + ACK 세그먼트 전송
1️⃣에 대한 호스트 B의 응답. 호스트 B는 ACK 비트와 SYN 비트가 1로 설정된 세그먼트를 호스트 A에게 전송
세그먼트의 순서 번호와 1️⃣에서 보낸 세그먼트에 대한 확인 응답 번호가 포함되어 있음

3️⃣ [송수신 방향 A → B] ACK 세그먼트 전송
호스트 A는 ACK 비트가 1로 설정된 세그먼트를 호스트 B에게 전송
세그먼트의 순서 번호에는 호스트 A의 순서 번호와 2️⃣에서 보낸 세그먼트에 대한 확인 응답 번호가 포함되어 있음

SYN: 연결을 수립하기 위한 비트
ACK: 연결이 수립되었음을 확인하는 비트

  • TCP 연결 수립 과정에서 SYN 비트가 설정된 패킷을 처음으로 보내는 호스트가 곧 처음으로 연결 요청을 보내는 호스트
  • 1️⃣ 에서 SYN 비트가 1로 설정된 패킷을 처음으로 보내는 호스트 A가 연결 요청을 처음으로 보내는 호스트인 셈
  • 액티브 오픈: 호스트 A처럼 처음 연결을 시작하는 과정
  • 패시브 오픈: 반대로 호스트 B처럼 연결 요청을 수신한 뒤 그에 대한 연결을 수립하는 과정

서버 - 클라이언트 관계에서 액티브 오픈은 주로 클라이언트에 의해 수행되고, 패시브 오픈은 주로 서버에 의해 수행됨


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

TCP는 송수신하는 패킷의 신뢰성을 보장하기 위해 크게 3가지 기능을 제공

  • 오류 제어 / 흐름 제어 / 혼잡 제어

1️⃣ 재전송을 통한 오류 제어

  • TCP는 송수신 과정에서 잘못 전송된 세그먼트가 있을 경우. 이를 재전송하여 오류를 제어
  • TCP는 "언제 잘못 전송된 세그먼트가 있음"을 인지하는 상황
    - 중복된 ACK 세그먼트가 도착했을 때
    - 타임아웃이 발생했을 때

중복된 ACK 세그먼트를 수신하는 상황

TCP의 송수신은 기본적으로 순서 번호를 담은 세그먼트를 보내고, 그에 대한 확인 응답이 담긴 세그먼트를 받고, 다음 순서 번호를 담은 세그먼트를 보내고, 다시 그에 대한 확인 응답이 담긴 세그먼트를 받고, 다시 보내고 받는 과정을 반복하며 이루어짐


타임아웃이 발생한 상황

TCP 세그먼트를 송신하는 호스트는 모두 재전송 타이머라는 특별한 값을 유지하는데, 호스트는 세그먼트를 전송할 때마다 이 재전송 타이머를 시작함. 이 타이머의 카운트다운이 끝난 상황을 타임아웃이라고 하며, 타임아웃 발생 시점까지 ACK 세그먼트를 받지 못하면 세그먼트 전송 과정에 문제가 발생했다고 간주하여 세그먼트를 재전송함


파이프라이닝 전송

TCP의 기본적인 송수신 방식에는 한 번에 여러 세그먼트를 보낼 수 있는 상황에서도 확인 응답을 받기 전까지는 보낼 수 없음. 다시 말해 한 번에 하나의 세그먼트만 주고받아야 하는 비효율이 있음

그래서 현대의 TCP는 그림과 같이 확인 응답을 받기 전이라도 여러 메시지를 보내는 방식으로 송신하며, 이를 파이프라이닝 전송이라고 부름


2️⃣ 흐름 제어

수신 호스트가 한 번에 n개의 바이트를 받아서 처리할 수 있다면 송신 호스트는 n개의 바이트를 넘지 않는 선에서 송신해야 함. TCP의 흐름 제어는 이처럼 수신 호스트가 한 번에 받아 처리할 수 있을 만큼만 전송하는 것을 의미
즉, 흐름 제어는 송신 호스트가 수신 호스트의 처리 속도를 고려하며 송수신 속도를 균일하게 맞추는 기능

3️⃣ 혼잡 제어

혼잡: 많은 트래픽으로 인해 패킷의 처리 속도가 느려지거나 유실될 수 있는 상황을 의미
혼잡 제어는 이러한 혼잡을 제어하기 위한 기능

  • 네트워크 혼잡 여부를 판단하는 기준은 세그먼트의 전송 오류를 판단하는 기준과 같음
  • 송신 호스트는 중복된 ACK 세그먼트가 도착했을 때, 그리고 타임아웃이 발생했을 때 "현재 네트워크가 혼잡 할 수 있다"고 판단
  • 혼잡 윈도우: 혼잡 없이 전송할 수 있을 정도의 양의 값
  • 혼잡 윈도우가 크면 한 번에 전송할 수 있는 세그먼트의 수가 많음을 의미하고, 반대로 혼잡 윈도우가 작으면 네트워크가 혼잡한 상황이므로 한 번에 전송할 수 있는 세그먼트의 수가 적음을 의미
  • TCP의 혼잡 제어를 수행하는 호스트는 각자 혼잡 윈도우 값을 고려하며, 혼잡 윈도우의 값을 넘지 않는 선에서 전송하게 됨
  • 혼잡 제어 알고리즘: 혼잡 윈도우 크기를 연산하는 방법, 즉 혼잡 제어를 수행하는 일련의 과정
  • AIMD: 가장 기본적인 혼잡 제어 알고리즘으로 세그먼트를 보내고, 그에 대한 응답이 오기까지 혼잡이 감지되지 않으면 혼잡 윈도우를 1씩 선형적으로 증가시키고, 혼잡이 감지되면 혼잡 윈도우를 절반으로 떨어뜨리는 동작을 반복하는 알고리즘

그래서 AIMD의 혼잡 윈도우는 그림과 같은 톱니 모양으로 변화한다는 특징이 있음

  • RTT: 패킷을 보내고 그에 대한 응답이 수신되기까지의 시간
  • 따라서 AIMD는 "혼잡이 감지되지 않으면 혼잡 윈도우를 RTT마다 1씩 선형적으로 증가시키고, 혼잡이 감지되면 혼잡 윈도우를 절반으로 떨어뜨리는 알고리즘"이라고 정의할 수도 있음

TCP의 종료

1️⃣ [송수빈 방향 A → B] FIN 세그먼트

  • 호스트 A는 FIN 비트가 1로 설정된 FIN 세그먼트를 호스트 B에게 전송

2️⃣ [송수신 방향 B → A] ACK 세그먼트

  • 1️⃣에 대한 호스트 B의 응답. 호스트 B는 ACK 세그먼트를 호스트 A에게 전송

3️⃣ [송수신 방향 B → A] FIN 세그먼트

  • 호스트 B는 FIN 세그먼트를 호스트 A에게 전송

4️⃣ [송수신 방향 A → B] ACK 세그먼트

  • 3️⃣에 대한 호스트 A의 응답. 호스트 A는 ACK 세그먼트를 호스트 B에게 전송

TCP 연결 수립 과정에서먼저 연결 요청을 보낸 호스트의 동작을 액티브 오픈, 연결 요청을 받아들이는 호스트의 동작을 패시브 오픈이라고 언급함
이와 유사하게 TCP의 연결 종료 과정에는 액티브 클로즈와 패시브 클로즈가 있음

액티브 클로즈: 먼저 연결을 종료하려는 호스트에 의해 수행되는 동작을 의미. 제시된 예시에서 먼저 연결 종료를 요청한 호스트는 A이므로 호스트 A에 의해 액티브 클로즈가 수행되었다고 할 수 있음

패시브 클로즈:예시의 호스트 B와 같이 연결 종료 요청을 받아들이는 호스트에 의해 수행되는 동작을 의미


TCP의 상태 관리

TCP는 상태를 유지하고 관리하는 프로토콜이라는 점에서 스테이트풀 프로토콜이라고도 부름
상태: 현재 어떤 통신 과정에 있는지를 나타내는 정보

TCP에는 다양한 상태가 존재하고, 호스트는 TCP를 통한 송수신 과정에서 다음과 같이 다양한 상태를 오가게 됨

1️⃣ 연결이 수립되지 않았을 때 주로 활용되는 상태

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

2️⃣ 연결 수립 과정에서 주로 활용되는 상태

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

3️⃣ 연결 종료 과정에서 주로 활용되는 상태

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

유의할 점은 패시브 클로즈 호스트가 마지막에 ACK 세그먼트를 수신하면 CLOSED 상태가 되는 반면, TIME-WAIT 상태에 접어든 액티브 클로즈 호스트는 일정 시간을 기다린 뒤 CLOSED 상태가 됨
일정 시간을 대기하는 이유는 마지막 ACK 세그먼트가 올바르게 전송되지 않았을 수 있고, 이 경우 재전송이 필요하기 때문

CLOSING 상태
CLOSING은 서로가 FIN 세그먼트를 보내고 받은 뒤 각자 그에 대한 ACK 세그먼트를 보냈지만, 아직 자신의 FIN 세그먼트에 대한 ACK 세그먼트를 받지 못했을 때 접어드는 상태




참고: 북스터디 - 이것이 취업을 위한 컴퓨터 과학이다 (Chapter 5-4)

profile
dock 사이즈 다르잖아

0개의 댓글