thumbnail
혼자 공부하는 네트워크 - 전송 계층과 TCP/UDP
Jul 28, 2024

혼공단 12기 4주차 학습 기록

transport layer

전송 계층(Transport Layer)의 개념과 주요 프로토콜 TCP, UDP에 대해 알아보자.

전송 계층(Transport Layer)

네트워크 계층의 IP는 비신뢰성 프로토콜이자, 비연결형 프로토콜이라는 한계를 지니고 있다.

비신뢰성 통신이란, 패킷이 수신지까지 제대로 전송된다는 보장을 하지 못한다는 것을 말한다. 전송 과정에서 패킷이 중복 또는 손상되거나 순서대로 도착하지 않더라도 결과는 보장하지 못한다는 것이다. 그래서 최선형 전달(best effort delivery)라고 부르기도 한다.

비연결형 통신이란, 이름 그대로 송수신 호스트 간 사전 연결을 진행하지 않고 수신지에 패킷을 전송하기만 하는 것이다.


언뜻 봤을 때는 책임 없이 데이터 전송에만 집중하는 것처럼 보일 수 있는데, 빠른 패킷 송수신을 위해서는 패킷 전송 확인이나 사전 연결과 같은 작업은 성능상 악영향을 끼칠 수 있기 때문에 어쩔 수 없다. 실시간 영상 통화나 스트리밍과 같은 상황에는 패킷 한두 개쯤 손실되더라도 시청에 큰 무리가 없기에 모든 경우에서 전송 과정이 신뢰성을 띠어야 하는 것은 아니다.

IP 한계 보완

전송 계층은 IP와 같이 비신뢰성, 비연결형 통신을 가능하게 하는 UDP라는 프로토콜과 IP의 한계를 보완하기 위해 연결형, 신뢰성 통신이 가능한 TCP라는 프로토콜을 함께 사용한다.

transport layer protocol

포트(port)

전송 계층은 패킷 내 송수신지 포트를 통해 특정 애플리케이션을 식별한다. 포트 번호는 16비트로 표현하며, 0번부터 65535번까지 할당할 수 있다. 번호의 범위에 따라 세 종류로 나뉜다.


잘 알려진 포트(Well known port)

0~1023번까지의 포트는 이름 그대로 널리 알려져 있고 유명한 포트 번호를 의미한다.


등록된 포트(registered port)

1024~49151번까지의 포트는 well known port보다는 덜 범용적이지만 흔하게 사용되는 애플리케이션 프로토콜에 할당하기 위해 사용된다.


동적 포트(dynamic port)

49152~65535번까지의 포트는 특별히 관리되지 않는 포트 번호로, 자유롭게 사용할 수 있다.


포트 번호 설명 포트 번호 설명
20, 21 FTP 443 HTTPS
22 SSH 1194 OpenVPN
23 TELNET 1433 Microsoft SQL Server DB
53 DNS 3306 MySQL DB
67, 68 DHCP 6379 Redis
80 HTTP 8080 HTTP 대체

IP 주소와 포트 번호를 모두 알고 있다면, 특정 호스트에서 어떤 애플리케이션 프로세스가 실행되고 있는지 식별할 수 있다. 그래서 포트 번호는 IP 주소와 함께 IP 주소:포트 번호 형태로 표기하는 경우가 많다.

port

아래 명령어로 chrome 브라우저의 포트 번호를 확인해보면,

$ lsof -i -P -n port number

로컬 포트

  • 62698번
  • 클라이언트가 원격 서버로 연결을 시작할 때, OS에 의해 자동으로 할당되는 동적 포트
  • 크롬 브라우저는 여러 웹사이트에 접속할 때 각각의 연결마다 다른 동적 포트를 사용하여 서로 다른 세션을 관리함

원격 포트

  • 443번
  • HTTPS 연결을 처리할 때 기본적으로 사용하는 well-known-port
  • 웹 브라우저가 HTTPS로 보호된 사이트에 접근할 때 사용됨

TCP(Transmission Control Protocol)

TCP는 전송 계층의 대표적인 프로토콜 중 하나로, 앞서 말했듯 연결형, 신뢰성 통신을 통해 IP의 한계를 보완한다.

TCP 세그먼트 구조

통신 단계를 살펴보기 이전에, TCP 세그먼트 구조를 이해해야 한다. TCP 세그먼트는 TCP에서 데이터를 전송할 때 사용되는 데이터의 기본 단위로 TCP 헤더 + 페이로드로 구성되어 있다. 그리고 TCP 헤더를 제외한 페이로드의 최대 크기는 MSS(Maximum Segment Size)라고 한다. 헤더의 크기까지 포함했던 MTU와는 대조적으로, MTU에서 IP 헤더와 TCP 헤더를 뺀 크기로 설정된다.

MSS

아래는 TCP 세그먼트에서 기본적으로 알아야 할 필드들이다.


송신지 포트(source port)/수신지 포트(destination port)

송수신지 애플리케이션을 식별하는 포트 번호가 명시되는 필드이다.


제어 비트(control bits)

기본적으로 8비트로 구성되며, 현재 세그먼트에 대한 부가 정보를 나타낸다. 플래그 비트(flag bits)라고도 부른다.

  • ACK: 세그먼트 승인을 나타내는 비트
  • SYN: 연결 수립을 위한 비트 (0 또는 1. 1이면 연결을 시작할 준비가 됨)
  • FIN: 연결 종료를 위한 비트

순서 번호(sequence number)

송수신되는 세그먼트의 올바른 순서 보장을 위해 첫 바이트에 부여되는 번호이다.

예를 들어, 응용 계층으로부터 전달 받은 데이터가 1800바이트이고 MSS가 500바이트라고 가정해 보자. 통신을 위해 연결을 수립하면, 제어 비트SYN이 1로 설정된 세그먼트는 순서 번호가 무작위 값인 초기 순서 번호(ISN: Initial Sequence Number)를 부여 받는다. 다음 순서 번호부터는 초기 순서 번호 + 송신한 바이트 수가 된다.

sequence number

확인 응답 번호(acknowledgment number)

상대 호스트가 보낸 세그먼트에 대한 응답으로, 다음 수신을 원하는 순서 번호가 명시된다. ACK 플래그를 1로 설정하면, 수신한 순서 번호 + 1인 확인 응답 번호를 전송하게 된다.

acknowledgment number

윈도우(window)

한 번에 수신하고자 하는 데이터(수신 윈도우)의 크기가 명시된다.

TCP 연결 과정 및 상태

TCP는 통신하기 연결을 수립하고 데이터 송수신 후 연결을 종료하는데, 이러한 과정에서 TCP는 다양한 상태(state)를 유지한다.


연결 수립 전

연결 수립이 이뤄지지 않았을 때는 주로 CLOSEDLISTEN 상태를 유지한다.

  • CLOSED: 어떠한 연결도 없는 상태
  • LISTEN: 연결 대기 상태

연결 수립

TCP 연결 수립은 3단계로 이루어진 3-way-handshake 방식으로 이루어진다.

  1. SYN (Synchronize)

    클라이언트가 서버로 SYN 플래그가 설정된 세그먼트를 전송하여 연결을 요청한다. 이때, 처음 연결을 요청하는 호스트의 연결 수립 과정을 액티브 오픈(active open)이라고 한다.

  2. SYN-ACK (Synchronize-Acknowledgment)

    서버는 클라이언트의 요청을 수신한 후, SYN-ACK 세그먼트를 클라이언트로 전송한다. 연결 요청을 받은 후, 요청에 따라 연결을 수립해 주는 과정은 패시브 오픈(passive open)이라고 한다.

  3. ACK (Acknowledgment) 클라이언트는 서버의 응답을 수신하고 ASK 세그먼트를 서버로 보내며 연결이 설정된다.

3 way handshake
  • SYN-SENT: 액티브 오픈 호스트가 SYN 세그먼트를 보낸 후, SYN-ACK 세그먼트를 기다리는 상태
  • SYN-RECEIVED: 패시브 오픈 호스트가 SYN-ACK 세그먼트 전송 후, ACK 세그먼트를 기다리는 상태
  • ESTABLISHED: 연결 수립을 나타내는 상태

연결 종료

TCP 연결 종료는 송수신 호스트가 각자 한 번씩 FIN과 ACK를 주고받는 4-way handshake 방식으로 이루어진다.

  1. FIN (Finish)

    클라이언트 또는 서버가 FIN 플래그가 설정된 세그먼트를 전송하면서 연결 종료를 요청한다. 먼저 연결을 종료하려는 호스트가 연결 종료 요청을 하는 방식을 액티브 클로즈(active close)라고 한다.

  2. ACK (Acknowledgment)

    요청을 받아들이는 상대는 FIN 세그먼트를 수신하고 ACK 세그먼트를 전송하여 연결 종료 요청을 확인한다. 상대방의 요청을 수신하여 연결을 종료하는 방식을 패시브 클로즈(passive close)라고 한다.

  3. FIN (Finish)

    처음 연결 종료를 요청한 호스트의 상대가 연결 종료 요청을 시작한다.

  4. ACK (Acknowledgment)

    마지막 ACK 세그먼트를 보내면서 연결이 완전히 종료된다.

4 way handshake
  • FIN-WAIT-1: 연결 종료 요청을 보낸 호스트가 접어드는 상태
  • CLOSE-WAIT: 연결 종료 요청을 받은 호스트가 FIN 세그먼트를 받은 후, ACK 세그먼트를 보낸 후 대기하는 상태
  • FIN-WAIT-2: FIN-WAIT-1 상태에서 ACK 세그먼트를 수신한 상태
  • LAST-ACK: 응용 프로그램이 종료를 준비하고 FIN 세그먼트를 전송한 후, ACK 세그먼트를 기다리는 상태
  • TIME-WAIT: 상대의 FIN 세그먼트를 수신하고 최종 ACK 세그먼트를 전송한 후 접어드는 상태. 이 상태에 접어든 액티브 클로즈 호스트는 패시브 클로즈 호스트와 달리 일정 시간을 기다린 뒤에 CLOSED 상태로 전환된다.
    *TIME-WAIT 상태가 필요한 이유: 마지막 ACK 세그먼트가 올바르게 전송되지 않았을 경우를 대비하기 위함

macOS 기준 netstat 또는 lsof -i -P -n 명령어로 응용 프로세스의 다양한 상태를 확인해 볼 수 있다.

TCP state

UDP(User Datagram Protocol)

UDP는 TCP와 달리 연결형 통신, 신뢰성 통신을 수행할 수 없는 프로토콜이다. 상태를 유지하지 않고 활용하지 않는다는 이유에서 스테이트리스(stateless) 프로토콜이라고도 한다.


TCP보다 기능이 적은 만큼 필드도 단순하다.

  • 송신지 포트(source port)/수신지 포트(destination port)

    송수신지 애플리케이션을 식별하는 포트 번호가 명시되는 필드이다.

  • 길이(length)

    헤더가 포함된 UDP 전체 데이터그램의 크기를 나타낸다.

  • 체크섬(checksum)

    데이터그램 전송 과정에서 오류가 발생했는지 검사하는 필드이다. 송신지가 데이터의 체크섬을 계산하고 수신지는 데이터의 무결성을 확인하여 체크섬이 일치하지 않는다면 데이터가 손상된 것으로 간주하여 폐기한다.


TCP는 데이터를 하나씩 확실히 전달하는 것이라 하면, UDP는 빠르게 전송하는 것에 목적을 두고 있기에 전송 과정에서 데이터가 손상되거나 순서가 바뀔 수도 있다.


TCP 오류 제어(Error Control)

TCP 오류 제어란 데이터 전송 중에 발생할 수 있는 데이터 손실, 중복, 손상 등을 감지하고 복구하는 메커니즘이다. 전송 과정에서 문제를 감지하면 해당 세그먼트를 재전송한다.

세그먼트를 재전송하는 상황은 두 가지가 있다.


  1. 중복된 ACK 세그먼트 전송

    호스트 A, B가 세그먼트를 주고받는 중에 손상된 세그먼트를 받게 되면 수신 측은 중복된 ACK 세그먼트를 전송하게 된다.

  2. 타임아웃 발생

    송신 측에서 ACK를 일정 시간 동안 수신하지 못하면 데이터를 재전송하게 된다. 이때 사용하는 타이머를 재전송 타이머(retransmission timer)라고 하며, 타이머가 끝나는 상황을 타임아웃(timeout)이라고 한다.


수신 호스트의 ACK와 타임아웃 발생을 토대로 문제가 생긴 데이터를 재전송하면서 신뢰성을 확보하는 방식을 ARQ(자동 재전송 요구)라고 한다. 대표적으로 3가지 방식을 알아보자.

Stop-and-Wait ARQ

가장 단순한 형식의 ARQ 프로토콜로, 수신 측이 ACK를 제대로 전송했는지 확인하기 전까지 대기하는 방식이다. ACK를 수신하면 다음 프레임을 전송하며, NAK(부정 응답)를 받거나 타임아웃이 발생하면 해당 프레임을 재전송한다.

Stop-and-Wait ARQ

구현이 간단하여 쉽게 이해하고 적용할 수 있지만, 한 번에 하나의 확인 응답을 할 수 있기 때문에 네트워크 효율성이 낮아 대역폭을 효과적으로 활용하지 못한다는 단점이 있다.

Go-Back-N ARQ

Stop-and-Wait ARQ의 비효율성을 개선한 방식으로, 송신 호스트가 수신 호스트의 ACK를 기다리지 않고 N개의 세그먼트를 연속적으로 전송하는 방식이다. 이러한 기술을 파이프라이닝(pipelining)이라고 한다. 오류 발생 시 해당 세그먼트 이후의 모든 세그먼트를 재전송해야 한다는 특징이 있다.

Go-Back-N ARQ

Go-Back-N ARQ는 ACK 수신을 기다리지 않고 연속 전송하므로 데이터 전송 효율은 높지만, 오류가 발생하면 많은 양의 중복 데이터를 전송할 수 있다는 단점이 있다.

Selective Repeat ARQ

Selective Repeat ARQ는 Go-Back-N ARQ의 중복 전송 문제를 해결하기 위한 방식으로, 송신 호스트는 오류가 발생한 특정 세그먼트만을 선택적으로 재전송한다. 데이터 전송의 효율성을 극대화할 수 있어 오늘날 대부분의 TCP 통신에서 사용하는 방식이다. (Selective Repeat ARQ가 지원되지 않는 경우에는 Go-Back-N ARQ 방식 사용)


TCP 흐름 제어(Flow Control)

흐름 제어는 송신 호스트의 데이터 전송 속도를 조절하여 수신 호스트의 버퍼 오버플로(buffer overflow)를 방지하는 메커니즘이다. 수신 측의 처리 능력에 맞게 데이터 전송 속도를 균일하게 유지한다.

오늘날 흐름 제어는 데이터의 ACK를 수신할 때마다 윈도우를 이동시키는 슬라이딩 윈도우(Sliding Window)를 사용한다. 여기서 윈도우(window)란, 확인 응답을 받지 않고도 한 번에 전송 가능한 데이터의 최대 크기이다.


아래 그림으로 쉽게 이해할 수 있다.

TCP sliding window

송신 호스트는 윈도우 크기(예시 4)만큼 데이터를 연속적으로 전송하고 수신 호스트는 수신 데이터에 대한 확인 응답을 전송한다. 0~4번째 세그먼트를 전송하고 0번째 세그먼트에 대한 ACK(1 ACK)를 받았다고 가정할 때, 송신 호스트는 윈도우를 다음 칸으로 1만큼 슬라이드 시킨다.

만약 데이터 전달 중 손실이 발생하면 해당 시점 이후의 모든 데이터를 재전송하는 Go-Back-N 방식 또는 손실된 데이터만 선택적으로 재전송하는 Selective Repeat 방식으로 오류 처리를 수행한다. 이 과정을 반복하면서 모든 데이터를 전송할 수 있게 된다.


TCP 혼잡 제어(Congestion Control)

혼잡 제어란 네트워크 혼잡 상태를 방지하고 완화하여 데이터 전송의 효율성을 높이는 메커니즘이다. 송신 호스트가 네트워크 혼잡도를 판단하고 해당 정도에 맞춰 유동적으로 전송량을 조절한다.

송신 호스트는 혼잡 없이 전송할 만한 데이터의 양인 혼잡 윈도우(congestion window)를 계산할 수 있어야 한다. 혼잡 윈도우의 크기는 혼잡 제어 알고리즘(congestion control algorithm)을 통해 결정할 수 있다.

혼잡 제어 알고리즘

가장 기본적인 혼잡 제어 알고리즘은 AIMD이다.


AIMD(Additive Increase/Multiplicative Decrease)

AIMD는 두 가지 기본 원칙에 따라 작동한다.

  • Additive Increase (AI): 네트워크가 안정적이라고 판단되면, 혼잡 윈도우 크기를 1만큼 선형적으로 증가시킨다.
  • Multiplicative Decrease (MD): 네트워크에 혼잡이 감지되면, 혼잡 윈도우를 기존의 절반으로 감소시킨다.

AIMD 기초적인 원칙을 제공하지만, 완전한 혼잡 제어를 제공하기에는 부족한 면이 있어 TCP는 추가 알고리즘을 도입한다.


느린 시작 알고리즘(slow start algorithm)

AIMD 방식은 선형적으로 혼잡 윈도우를 증가시키기 때문에 초기 연결 시에는 전송 속도가 확보되지 않는다. 이 한계를 극복하기 위해 느린 시작 알고리즘은 혼잡 윈도우를 1부터 시작해 연결 초기 단계에서 전송 속도를 급격히 증가시켜 혼잡을 완화한다.

다만, 혼잡 윈도우를 지속적으로 증가시키다 보면 혼잡을 마주할 확률이 높아지므로 느린 시작 임계치(slow start threshold)라는 값을 설정하여 해당 임계치 미만에서만 증가하도록 한다.


혼잡 회피 알고리즘(congestion avoidance algorithm)

혼잡 회피 알고리즘은 네트워크가 혼잡 상태로 진입하기 전에 전송 속도를 조절하여 혼잡을 방지한다. 혼잡 윈도우를 지수적으로 증가시키는 느린 시작 알고리즘과는 달리, RTT마다 혼잡 윈도우를 1MSS씩 선형적으로 증가시킨다. 느린 시작 임계치를 넘어선 시점에 혼잡이 발생할 우려가 있기에 미리 조심해서 증가시키는 방식이라고 생각하면 된다.


빠른 회복 알고리즘(fast recovery algorithm)

AIMD 원칙을 따르면서도 데이터 손실 후의 전송 속도를 좀 더 빠르게 회복하기 위해 사용하는 알고리즘이다. 세 번의 중복 ACK 세그먼트를 수신하면, 느린 시작은 건너뛰고 혼잡 회피를 수행한다.

TCP congestion control

기본 미션

MISSION 1

1. IP와 연관된 통신 특성으로 알맞은 단어를 <보기>에서 골라 보세요. (p.206)

신뢰성, 연결형, 비신뢰성, 비연결형

정답: 비신뢰성, 비연결형

MISSION 2

2. 다음은 TCP 쓰리 웨이 핸드셰이크 과정을 나타내는 그림입니다. 괄호 안에 들어갈 말을 <보기>에서 골라 보세요. (p.225)

SYN, ACK, FIN

misson 2

정답: ACK


추가 미션

MISSION 1

Q. 작업 관리자에서 프로세스별 PID 확인해 보기


macOS 기준, 터미널에 아래 명령어를 입력한 후, 두 번째 열을 확인하면 해당 포트를 사용 중인 프로세스의 PID를 알 수 있다.

$ lsof -i -P -n 프로세스별 PID 확인

References

[📚book] 혼자 공부하는 네트워크

Table Of Contents
nxnaxx blog © 2022-2024 Powered By Gatsby.