포스트

[Network] TCP VS UDP

Computer Science / Network

TCP와 UDP를 비교하여 개념을 정리

Protocol(프로토콜)?

결론을 먼저 말하자면, HTTP, IP, TCP, UDP 모두 프로토콜이며, 프로토콜은 클라이언트와 서버가 정보를 교환하기 위한 일종의 메시지 형식의 규칙이다.

프로토콜(Protocol)은 클라이언트와 서버가 정보를 교환할 수 있도록 하는 메시지 형식에 대한 규칙이라고 보면 된다.

수신 호스트가 전송받은 메시지를 이해하기 위해서는 설계된 규칙에 따라 작성된 데이터 형식이어야 한다는 것이다.

예를 들어 HTTP 메시지 헤더도 결국 일종의 규칙이며, IP 주소의 숫자도 규칙이라고 말할 수 있다.

IP의 규칙을 깨는 256.256.256.256과 같은 형식의 IP 주소는 존재하지도 않으며, 작동하지도 않는다.

TCP (Transmission Control Protocol, 전송 제어 프로토콜)

IP(Internet Protocol)가 인터넷 프로토콜로서 복잡한 인터넷 망 속에서 클라이언트와 서버 간의 통신을 할 수 있게 IP 주소, 패킷과 같은 규칙을 통해 통신을 하는 것이라면,

TCP(Transmission Control Protocol)는 IP 규칙으로만 통신하기에 부족하거나 불안정하던 여러 단점들(패킷 순서가 이상하거나 패킷이 유실)을 커버해, 패킷 전송을 제어하여 신뢰성을 보증하는 프로토콜로 보면 된다.

IP와 TCP 둘 다 프로토콜이지만 이 둘을 동일시하면 안되는게, 이 둘의 규칙은 별개이다.

IP 규칙으로 써있는대로 목적지에 도착했으면 TCP 규칙으로 써있는대로 올바르게 도착했는지, 정확히 누구에게 전달되어야 하는지 등 하나씩 전부 따진다고 생각하면 된다.

그래서 은행 업무나 메일과 같은 반드시 수신자가 정보를 받아야 하는 신뢰성 있는 통신이 필요할 때 사용된다.

TCP의 전송 데이터 포장

image_4

TCP의 인터넷 통신을 위한 전송 데이터 포장 방식은 위의 이미지와 같다.

추가적인 예시를 들자면, 택배 수화물로 비유할 수 있다.

IP는 단순히 배달 주소지라고 한다면, TCP는 이 배달지로 문제없이 전송되도록 택배 스티커와 같은 여러 부가 정보들을 가미한 것이라고 볼 수 있다.

단순히 목적지 뿐만 아니라 순서, 검증, 전송 제어 정보가 들어있어 IP 주소지로만 물품을 배달하기엔 불안정한 부분들을 확실하게 커버하여 배달품이 목적지까지 안전하게 도착하도록 보증한다.

image_5

위의 이미지는 전송 데이터가 포장되는 과정을 나열한 것이다.

  1. 전송 데이터를 TCP 방식으로 포장한다.
  2. 포장한 전송 데이터를 IP 방식으로 포장한다.
  3. 포장한 전송 데이터를 Ethernet 방식으로 포장한다.
  4. 인터넷을 통해 상대 컴퓨터 서버에 도달하여 포장된 것을 하나씩 풀며 전송 데이터를 받게 된다.

TCP의 통신 확인

TCP는 신뢰성 프로토콜답게, 데이터를 전송하기 전에 목적지가 무사한지를 미리 확인하고, 데이터의 전송이 끝난 후에도 다시 확인 해주는 굉장히 친절하고 꼼꼼한 프로토콜이다.

통신을 시작할 때와 종료할 때 서로 준비가 되어있는지를 반드시 미리 먼저 물어보고 패킷을 전송할 순서를 정하고 나서야 본격적으로 통신을 시작하기 때문이다.

이러한 과정이 바로 3-Way Handshake4-Way Handshake 과정이다.

둘 다 똑같은 핸드쉐이크(Handshake)지만, 3-Way는 통신을 시작할 때, 4-Way는 통신이 종료될 때 거치는 과정이라는 차이만 있다.

즉, 한 번 통신하는데 핸드쉐이크를 두 번 진행해서 과할 정도로 신뢰성을 보장한다고 생각하면 된다.

image_6

위의 이미지에서 클라이언트가 처음 서버와 통신을 하기 위해 TCP 연결을 생성할 때, SYNACK라는 패킷을 주고 받으며, 통신을 종료하는 과정에서는 FIN이라는 패킷을 주고 받고 있는 것 볼 수 있다.

즉, 패킷 내부에 들어있는 인증 플래그 값들을 확인해서 클라이언트와 서버가 서로 보낸 패킷의 순서와 패킷을 제대로 받았는지를 검증하는 것이다.

Flag 종류

FLAG설명
SYN접속 요청을 할 때 보내는 패킷을 말한다.
TCP 접속 시에 가장 먼저 보내는 패킷이다.
ACK상대방으로부터 패킷을 받은 뒤에 잘 받았다고 알려주는 패킷을 말한다.
다른 플래그와 같이 출력되는 경우도 있다.
PSH데이터를 즉시 목적지로 보내라는 의미이다.
FIN접속 종료를 위한 플래그이다.
이 패킷을 보내는 곳이 현재 접속하고 있는 곳과 접속을 끊고자 할 때 사용한다.

3-Way Handshake의 과정

image_7

  1. 클라이언트는 접속을 요청하는 SYN 패킷을 보낸다.

    이때, 클라이언트는 응답을 기다리기 위해 SYN_SENT 상태로 변한다.

  2. LISTEN 상태였던 서버는 SYN 요청을 받으면, 클라이언트에게 요청을 수락하는 ACK 패킷과 SYN 패킷을 보낸다.

    서버도 클라이언트에 접속해야 양방향 통신이 되기 때문이다.

    그리고 SYN_RCVD(SYN_RECEIVED) 상태로 변하여 클라이언트가 ACK 패킷을 보낼 때까지 기다리게 된다.

  3. 클라이언트는 다시 서버에 ACK 패킷을 보내고, 이후에 ESTABLISHED 상태가 되어 데이터 통신이 가능하게 된다.

데이터 통신 과정

image_8

  1. ESTABLISHED된 상태에서 서버에게 데이터를 보낸다.
  2. 서버는 잘 전송받았다고 ACK 플래스를 넣어 응답한다.
  3. 만약 클라이언트가 서버로부터 ACK를 받지 못했다면, 제대로 송신하지 못한걸로 판단하고 데이터를 재전송한다.

4-Way Handshake의 과정

image_9

  1. 서버와 클라이언트가 TCP 연결이 되어있는 상태에서 클라이언트가 접속을 끊기 위해 CLOSE() 함수를 호출한다.

    그러면 FIN 플래그를 보내게 되고, 클라이언트는 FIN_WAIT1 상태로 변한다.

  2. 서버는 클라이언트가 CLOSE() 함수를 호출한 것을 알게되고, CLOSE_WAIT 상태로 바꾼 후, ACK 플래그를 전송한다.

    만일 서버에서 클라이언트로 보내야 하는 남은 데이터가 있을 경우, 이 과정에서 나머지를 모두 전송시킨다.

  3. ACK를 받은 클라이언트는 FIN_WAIT2로 변환되고, 이떄 서버는 CLOSE() 함수를 호출하고 FIN 플래그를 클라이언트에게 보낸다.
  4. 서버도 연결을 닫았다는 신호를 클라이언트가 수신하면, ACK 플래그를 보낸 후 TIME_WAIT 상태로 전환된다.

    이 후, 모든 것이 끝나면 CLOSED 상태로 변환된다.

TCP 통신 과정 시각적으로 확인하기

TCP 핸드쉐이크 과정을 시각적으로 확인하기 위해 Linux 명령어를 통해 진행할 예정이다.

https://www.wireshark.org/ → 와이어샤크라는 무료 소프트웨어를 사용해서 확인하는 방법도 있다.

위에서 설명한 데이터 통신 이미지와는 살짝 다른 결과가 나와서 전체적으로 추?측으로 글을 작성했으며, 정확한 답을 찾게 되면 수정 예정

Linux tcpdump로 확인하기

tcpdump는 Linux 환경에서 클라이언트와 서버가 주고받는 네트워크 패킷을 TCP layer에서 캡쳐하여 메시지를 확인할 수 있는 명령어로, UDP도 확인이 가능하다.

먼저 아래의 명령어를 통해 tcpdump 명령어를 설치한다.

필자의 맥 세팅의 경우, Homebrew를 통해 설치를 진행

1
2
3
4
5
6
7
8
# 우분투 설치
apt install tcpdump

# CentOS 설치
yum install tcpdump

# Homebrew 설치
brew install tcpdump

위의 명령어를 통해 설치가 끝났다면, 아래의 명령어를 실행한다.

1
2
# 인터넷 통신을 하는 모든 프로토콜 감지 명령어
sudo tcpdump -i en1 -c 10 # MacOS의 경우, sudo
  • -i <interface>
    인터페이스 지정
  • -c <count>
    지정한 카운트 패킷을 수신한 후 종료

en1 등의 네트워크를 알고 싶다면 “이 Mac에 관하여” → “추가 정보” → 맨 아래의 “시스템 리포트” → “네트워크”

위와 같이 옵션을 지정해서 명령어를 실행하면,

1
2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on en1, link-type EN10MB (Ethernet), snapshot length 262144 bytes

위와 같이 인터넷 통신을 감지하는 상태가 되고, 인터넷 통신이 감지가 된다면,

1
14:34:53.316116 IP XXX.XX.X.X.mdns > mdns.mcast.net.mdns: 0*- [0q] 2/0/0 PTR _airplay._tcp.local., PTR _raop._tcp.local. (88)

위와 같은 네트워크 통신 로그를 볼 수 있다.

그렇다면 직접 통신을 진행시키고 로그를 확인해보도록 한다.

  1. 80번 포트로 지정해서 인터넷 통신을 LISTEN 상태로 실행

    1
    
    sudo tcpdump -i en1 port 80 # 추가적으로 포트 80번으로 지정
    
  2. 새로운 터미널을 열어서 임의로 80번 포트에 네트워크 통신을 진행

    1
    
    echo "Hello World" | nc naver.com 80
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    HTTP/1.1 400 Bad request
    Content-length: 90
    Cache-Control: no-cache
    Connection: close
    Content-Type: text/html
    
    <html><body><h1>400 Bad request</h1>
    Your browser sent an invalid request.
    </body></html>
    

    존재하지 않는 서버로 당연히 통신 에러

  3. 인터넷 통신을 LISTEN 상태로 유지하고 있는 터미널 확인

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    14:47:51.551763 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [S], seq 1493362503, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3305467768 ecr 0,sackOK,eol], length 0
    14:47:51.564850 IP 223.130.200.219.http > 172.30.1.45.54147: Flags [S.], seq 1123520104, ack 1493362504, win 28960, options [mss 1440,sackOK,TS val 222617396 ecr 3305467768,nop,wscale 11], length 0
    14:47:51.565151 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [.], ack 1, win 2052, options [nop,nop,TS val 3305467782 ecr 222617396], length 0
    14:47:51.565245 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [P.], seq 1:13, ack 1, win 2052, options [nop,nop,TS val 3305467782 ecr 222617396], length 12: HTTP
    14:47:51.565267 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [F.], seq 13, ack 1, win 2052, options [nop,nop,TS val 3305467782 ecr 222617396], length 0
    14:47:51.578659 IP 223.130.200.219.http > 172.30.1.45.54147: Flags [P.], seq 1:208, ack 14, win 15, options [nop,nop,TS val 222617407 ecr 3305467782], length 207: HTTP: HTTP/1.1 400 Bad request
    14:47:51.578661 IP 223.130.200.219.http > 172.30.1.45.54147: Flags [F.], seq 208, ack 14, win 15, options [nop,nop,TS val 222617407 ecr 3305467782], length 0
    14:47:51.578941 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [.], ack 208, win 2049, options [nop,nop,TS val 3305467795 ecr 222617407], length 0
    14:47:51.579090 IP 172.30.1.45.54147 > 223.130.200.219.http: Flags [.], ack 209, win 2049, options [nop,nop,TS val 3305467795 ecr 222617407], length 0
    
  • 172.30.1.45.54147
    클라이언트 IP
  • 223.130.200.219.http
    서버 IP (HTTP → 80)
  • 172.30.1.45.54147 > 223.130.200.219.http
    “클라이언트가 서버에게” → “보내는 쪽 > 받는 쪽”
  • Flags [S, S., ., P., F.]
    앞서 설명한 플래그를 의미
    Flag이름
    SSYN
    S.SYN-ACK
    .ACK
    PPSH
    FFIN

3-Way Handshake 과정

image_10

  1. 클라이언트(172.30.1.45) → 서버(223.130.200.219) : [SYN], [S]
  2. 서버(223.130.200.219) → 클라이언트(172.30.1.45) : [SYN-ACK], [S.]
  3. 클라이언트(172.30.1.45) → 서버(223.130.200.219) : [ACK], [.]

seq 번호는 순서 번호로써, 패킷의 전달 순서를 식별하는데 사용되는 값이다.

운영체제에 의해서 랜덤하게 생성되서 SYN 패킷에 담겨서 보내지며, 이를 받은 서버에는 동기화에 대한 답신으로 seq 번호를 +1 증가시키고 ack에 담아 응답한다.

데이터 통신 과정

image_11

  1. 클라이언트(172.30.1.45) → 서버(223.130.200.219) : [PSH-ACK], [P.]
  2. 클라이언트(172.30.1.45) → 서버(223.130.200.219) : [FIN-ACK], [F.]
    • 예상해보자면, 서버 측에서 통신 오류로 인해 PSH-ACK 이후에 바로 FIN-ACK로 통신을 종료시킨 듯 하다. (더 알아보고 답을 찾을 예정)
  3. 서버(223.130.200.219) → 클라이언트(172.30.1.45) : [PSH-ACK], [P.]
    • 해당 로그의 정보로 HTTP: HTTP/1.1 400 Bad request 로그가 있는 것으로 봐서, 서버 측에서 에러를 클라이언트에게 PSH-ACK한 작업으로 보인다. (더 알아보고 답을 찾을 예정)
  4. 서버(223.130.200.219) → 클라이언트(172.30.1.45) : [FIN-ACK], [F.]

4-Way Handshake 과정

image_12

최종적으로 위에서 설명한 것처럼 클라이언트와 서버 간의 통신은 이미 FIN-ACK를 통해 끊긴 상황이므로 추가적인 통신에 대한 플래그가 존재하지 않는다.

즉, 통신에 대한 플래그가 없기 때문에 .을 통한 Placeholder가 찍힌다. (추?측, 더 알아보고 답을 찾을 예정)

  1. 클라이언트(172.30.1.45) → 서버(223.130.200.219) : [ACK], [.]

TCP의 전송 제어 기법

TCP 제어 알고리즘은 굉장히 양도 많고 난이도 자체도 높기 때문에 별도로 공부가 필요

해당 게시글의 경우, 기초와 개념 잡기를 중점으로 작성

TCP(Transmission Control Protocol)는 단어 그대로 원활한 통신을 위해 전송 흐름을 제어하는 기능을 프로토콜 자체에 포함하고 있다.

만약 TCP가 없었다면, 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야 하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에, 덕분에 우리같은 개발자들은 온전히 상위의 동작에만 집중할 수 있게 된 것이다.

보통 TCP의 전송 제어 방법으로 3가지가 있다.

흐름 제어 (Flow Control)

수신자가 처리할 수 있는 데이터 속도가 다르기 때문에, 송신 측은 수신 측의 데이터 처리 속도를 파악하고 얼마나 빠르게 어느 정도의 데이터를 전송할 지 제어하는 기법이다.

슬라이딩 윈도우(Sliding Window) 방식을 사용한다.

  • 슬라이딩 윈도우 (Sliding Window)
    Window라는 데이터를 담는 공간을 동적으로 조절하여 데이터의 양을 조절
    image_13

오류 제어 (Error Control)

통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우에 대처하는 제어 기법이다.

Go Bank N 기법Selective Repeat(선택적인 재전송) 기법을 사용한다.

image_14

  • Go Bank N 기법
    어느 데이터로부터 오류가 발생했는지 파악하고, 그 부분만 다시 순서대로 보내어 제어한다.
  • Selective Repeat 기법
    에러가 발생한 데이터만 재전송하고, 그 전에 받았던 순서가 잘못된 데이터 버퍼를 재정렬하여 제어한다.

혼잡 제어 (Congestion Control)

image_15

네트워크가 불안정하여 데이터가 원활히 통신이 안되면 제어를 통해 재전송을 하게 되는데, 재전송 작업이 반복되면 네트워크가 붕괴될 수도 있다.

따라서 네트워크 혼잡 상태가 감지되면 송신 측의 전송 데이터 크기를 조절하여 전송량을 조절한다.

TCP에는 Tahoe, Reno, New Reno, Cubic, Elastic-TCP 등등 다양한 혼잡 제어 기법이 존재한다.

TCP의 헤더 구성

image_16 TCP의 경우, 워낙 오래 전에 설계되기도 했고, 여러가지의 기능이 많이 포함된 프로토콜이다보니 이미 헤더가 거의 풀로 채워져 있다.

  • Source Port
    데이터를 생성한 애플리케이션에서 사용하는 포트 번호
  • Destination Port
    목적지 애플리케이션이 사용하는 포트 번호
  • Sequence Number 필드
    세그먼트(Segment) 순서를 맞추기 위한 필드
  • Acknowledgement Number 필드
    다음 세그먼트(Segment) 순서를 맞추기 위한 필드
  • Data Offset 필드
    TCP 헤더의 크기

    5~15 : $5\times32$<160bit> ~ $15\times32$<480bit>

  • Reserved 필드
    차후의 사용을 위한 예약된 필드
  • Control Flags (SYN, ACK, FIN 등…)
    긴급, 혼잡, 확인, 수신 거부 등의 기능
  • Window Size 필드
    수신자가 한번에 받을 수 있는 데이터의 양
    송신자는 Window Size만큼 ACK를 기다리지 않고 데이터를 전송하며, ACK가 계속 왔다갔다 하지 않아도 된다.
  • Checksum
    세그먼트(Segment) 내용의 유효성과 손상 여부 검사

UDP (User Datagram Protocol, 사용자 데이터그램 프로토콜)

보통 UDP와 TCP를 비교하는데에 있어서 “TCP는 신뢰성이 높고 느리다.”“UDP는 신뢰성이 낮고 빠르다.” 정도로 정리를 할 수 있다.

 TCPUDP
연결 방식연결형 서비스비연결형 서비스
패킷 교환가상 회선 방식데이터그램 방식
전송 순서 보장보장함보장하지 않음
신뢰성높음낮음
전송 속도느릠빠름

위의 표의 내용의 요약된 내용인 셈이다.

TCP의 경우에는 핸드쉐이크 과정을 거치게 되는데, 위에서 설명한 것처럼 데이터 하나를 전송하기 위한 밑작업들이 많다.

결국 거치는 작업들이 많을 수록 데이터 전송이 비교적 느려진다는 뜻인데, 인터넷 기술이 발전하면서 전송해야 하는 데이터도 단순 텍스트가 아닌 영상이나, 음악과 같은 멀티미디어도 전송하면서 데이터의 크기가 점점 커져가면 동시에 빠른 통신이 필요하게 된다.

그래서 HTTP/1.1의 다음 버전인 HTTP/2.0[^http2.0]에서는 한 번 연결된 TCP 회선을 길게 유지하고 데이터도 스트림이라는 특수한 형태로 보내는 식으로 극복을 했지만, TCP 자체가 가지는 근본적인 특징으로 인해 결과적으로 속도의 한계가 존재했다.

즉, 인터넷 통신의 방식 자체가 너무 무거워서 더이상 속도를 뽑아낼 수가 없다.

반면, UDP(User Datagram Protocol)는 데이터그램 방식을 사용하는 프로토콜이기 때문에 애초에 각각의 패킷 간의 순서가 존재하지 않는 독립적인 패킷을 사용한다.

데이터그램 방식은 패킷의 목적지만 정해져 있다면 중간 경로는 어디를 타든 신경쓰지 않기 때문에, 핸드쉐이크 과정 같은 연결 설정이 필요없게 된다.

즉, UDP는 신뢰성을 확보하기 위해 TCP 방식이 거치는 과정을 거치지 않기 때문에 속도가 더 빠를 수 밖에 없다는 것이다.

그래서 UDP는 실시간 영상 스트리밍과 같은 고용량 데이터를 다루는 곳에 이용된다.

UDP의 통신 시각적으로 확인하기

UDP가 왜 TCP보다 빠른지에 대해서는 Linux 명령어를 통해서도 바로 이해할 수 있다.

위에서 TCP 통신을 위해 입력한 명령에 중,

1
2
3
4
5
echo "Hello World" | nc naver.com 80
# 위의 명령어에서

echo "Hello World" | nc -u naver.com 80
# 위와 같이 -u 옵션을 붙이고 실행

위와 같이 명령어의 옵션을 변경하여 실행하면,

1
14:32:59.429809 IP 172.30.1.45.55545 > 223.130.200.236.http: UDP, length 12

이러한 결과가 나오며 통신이 종료된다.

위의 인터넷 통신을 이미지로 표현하면 아래와 같다.

image_17

UDP의 헤더 구성

image_18 TCP와는 다르게 UDP는 데이터 전송 자체에만 초점을 맞추고 설계되었기에 헤더에 들어있는 것이 없다. (채울 수 있는 공간(커스텀이 가능한 공간)이 많다는 뜻도 됨)

UDP의 헤더에는 출발지와 도착지, 패킷의 길이와 체크섬 밖에 없다.

  • Source Port
    데이터를 생성한 애플리케이션에서 사용하는 포트 번호
  • Destination Port
    목적지 애플리케이션이 사용하는 포트 번호
  • Checksum
    중복 검사의 한 형태로, 오류 정정을 통해 공간(전자 통신)이나 시간(기억 장치) 속에서 송신된 자료의 무결성을 보호하는 단순한 방법

    TCP의 체크섬과는 다르게 UDP의 체크섬은 필수가 아닌 선택사항이다.

UDP를 선택한 HTTP 3.0

최근에 HTTP/2.0의 다음 버전인 HTTP/3.0가 새롭게 표준화되었는데, HTTP/3.0가 UDP를 채택했다.

현재 Google, Naver, Netflix 등의 많은 사이트들이 지원하고 있으며,

2022년 11월에 한국 최초로 네이버에서 HTTP/3.0를 도입했다고 한다.

대부분의 메이저한 웹 브라우저 역시 지원하고 있다.

웹 브라우저 지원에 대한 내용은 Can I use…에서 확인할 수 있다.

또한 AWS와 같은 클라우드 서비스에서도 일부 서비스에 HTTP/3.0를 사용할 수 있는 옵션을 지원한다.

UDP를 선택한 이유는 무엇인가?

이유 1. TCP는 개선해도 여전히 느리다.

TCP가 만들어진 1970년대에는 아마 현재와 같이 클라이언트와 서버가 동시 다발적으로 여러 개의 파일의 데이터 패킷을 교환할 수 있게 될 것이라고는 상상도 못했을 것이다.

동시 다발적인 데이터 통신이 불가능했던 그 당시에는 무엇보다도 중요했던 것이 바로 데이터 통신의 안전성과 신뢰성이라고 생각했던 것 같다.

그래서 모바일 기기와 같은 네트워크 환경을 바꿔가면서 서버와 클라이언트가 소통할 수 있을 것이라고 생각하지 못했다.

그 때문에 와이파이를 바꾸면 다시 새로운 커넥션을 맺어야 되서 끊김 현상이 일어나는 것이다.

클라이언트 측에서 네트워크를 쉽게 바꿀 수가 없었기에 애초에 새로운 커넥션에 대한 고려 조차도 하지 않았을 것이다.

또한 TCP를 사용한 통신에서의 패킷은 신뢰성을 위해 무조건 순서대로 처리되어야 한다.

더군다나, 패킷이 처리되는 순서 또한 정해져있으므로 이전에 받은 패킷을 파싱하기 전까지는 다음 패킷을 처리할 수도 없다.

만일, 중간에 패킷이 손실되어 수신 측이 패킷을 제대로 받지 못했디면, 다시 보내야 한다.

이렇게 패킷이 중간에 유실되거나 수신 측의 패킷 파싱 속도가 느리다면 통신에 병목 현상이 발생하게 되는데, 이러한 현상을 HOL(Head of Line) Blocking라고 부른다.

이 HOL(Head of Line) Blocking 현상은 TCP 설계 상 어쩔 수 없이 발생하는 문제이기 때문에 HTTP/1.1 뿐만 아니라 HTTP/2.0도 가지고 있는 고질적인 문제였다.

이러한 고질적인 문제들을 해결하기 위해 HTTP/3.0는 결국 TCP와의 이별을 선언하고 UDP를 선택했다.

이유 2. UDP의 신뢰성은 커스터마이징하면 그만이다.

앞서 신뢰성 대신 속도를 택한 UDP는 스트리밍과 같은 서비스에서 사용된다고 설명한 바가 있다.

방송이나 동영상은 중간에 끊기더라도 바로바로 데이터를 빠르게 송출해서 영상을 다시 재생시키는 것이 더 중요하기 때문이다.

하지만 기본적으로 인터넷은 클라이언트와 서버 간의 정확한 패킷 통신이 필요하기 때문에 신뢰성을 보장받아야 한다.

이것이 바로 HTTP가 TCP를 기반으로 했는지에 대한 이유이다.

여기서 오해가 생길 수 있는 부분이 바로 UDP는 빠르긴 하지만 신뢰성이 없기 때문에 사용성이 적다고 생각하는 부분인데, 사실 이는 명확하지 않다.

앞서 UDP의 헤더 구성👆에서도 볼 수 있듯이, UDP의 헤더는 커스터마이징을 할 수 있는 공간이 많다는 것을 잊어서는 안된다.

즉, UDP는 신뢰성이 없는 것이 아닌, 탑재를 안했을 뿐이다.

다시 말하자면, UDP 자체의 헤더는 비어있기 때문에 신뢰성도 낮고 제어 기능도 없지만, 개발자가 애플리케이션에서 구현을 어떻게 하냐에 따라서 TCP와 비슷한 수준으로 신뢰성이 높을 수도, 훌륭한 제어 기능을 가질 수도 있다는 말이다.

UDP를 개조한 QUIC 프로토콜

image_19

QUIC(Quick UDP Internet Connection)는 UDP를 기반으로 TCP, TLS, HTTP의 기능을 모두 구현하는 프로토콜이다. (만능?)

따라서, HTTP/3.0이 UDP를 채택했다는 말은 정확히는 UDP 기반으로 만들어진 QUIC 프로토콜을 채택했다는 뜻이다.

image_20

QUIC는 TCP를 사용하지 않기 때문에 통신을 시작할 때 번거롭던 3-Way Handshake 과정을 거치지 않아도 된다.

클라이언트가 보낸 요청을 서버가 처리한 후 다시 클라이언트로 응답해주는 사이클을 RTT(Round Trip Time)라고 하는데, TCP는 연결을 생성하기 위해 기본적으로 1RTT가 필요하고, 여기에 TLS를 사용한 암호화까지 하려고 한다면 TLS 자체의 핸드쉐이크까지 더해져서 총 3RTT가 필요하다.

반면 QUIC는 첫 연결 설정에 1RTT만 소요된다.

TCP 핸드쉐이크 과정을 거치지 않으면서 TLS 자체를 내포하고 있기 때문에 연결 설정에 필요한 정보와 함께 보내버리기 때문이다.

또한 한번 연결에 성공했다면, 서버는 그 설정을 캐싱해놓고 있다가 다음 연결 때는 캐싱해놓은 설정을 사용하여 바로 연결을 성립시키기 때문에, 0RTT만으로 바로 통신을 시작할 수도 있다.

이 외에도 패킷 손실 감지에 걸리는 시간이 단축되었으며, 클라이언트의 IP가 바뀌어도 연결이 유지되어 모바일에서 와이파이를 바꿔도 끊김이 없어지게 되었다.

참고 사이트

Inpa Dev - 🌐 아직도 모호한 TCP / UDP 개념 ❓ 쉽게 이해하자

Z.com Cloud - So sánh chi tiết TCP và UDP: Chọn giao thức nào tốt nhất?

위키백과 - 전송 제어 프로토콜


이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.