본문으로 건너뛰기

TCP, UDP, TLS

브라우저 주소창에 https://asap-note.pages.dev 를 입력하면 화면이 뜨기까지 TCP, UDP, TLS 가 차례로 쓰입니다. 세 가지는 서로 다른 문제를 풉니다. 데이터가 빠짐없이 도착하는지, 얼마나 빨리 도착하는지, 중간에서 누가 볼 수 없는지입니다.

이 글은 각각이 무엇을 해결하는지 그림과 코드로 확인하고, 마지막에 한 번의 HTTPS 요청에서 세 가지가 어떻게 이어지는지 봅니다.


1. 통신하려면 무엇이 필요할까​

브라우저(클라이언트)가 요청을 보내면 서버가 응답합니다. 요청과 응답 데이터는 한 번에 전송되지 않고 여러 조각으로 나뉘어 이동합니다.

패킷은 전송을 위해 나눈 데이터 조각 하나입니다. 목적지 주소 같은 제어 정보를 담은 헤더와 실제 데이터로 이루어집니다. TCP 에서는 세그먼트, UDP 에서는 데이터그램이라고도 부르지만 이 글에서는 패킷으로 통일합니다.

패킷이 어디로 가야 하는지, 도중에 사라지면 어떻게 하는지, 중간에서 읽히면 어떻게 하는지를 미리 정해 두어야 통신이 됩니다.

1.1 IP, 포트, 프로토콜​

  • IP 주소: 네트워크에서 컴퓨터 한 대를 식별하는 번호입니다. 예: 198.51.100.7
  • 포트: 한 컴퓨터 안에서 통신하는 프로그램을 식별하는 0~65535 사이의 번호입니다.
  • 프로토콜: 주고받는 데이터의 형식과 순서를 정한 규칙입니다. HTTP, TCP, UDP, TLS 가 모두 프로토콜입니다.

연결의 목적지는 IP 주소와 포트 번호 한 쌍으로 정해집니다.

브라우저는 IP 203.0.113.5 와 임시 포트 52814 를 가지고, 서버는 IP 198.51.100.7 에서 443번 포트는 HTTPS 서버, 80번은 HTTP 서버, 53번은 DNS 서버가 사용한다. 브라우저가 52814번 포트에서 서버의 443번 포트로 연결한다

서버는 같은 IP 주소에서 포트 번호로 서비스를 나눕니다. 웹은 관례적으로 HTTP 가 80, HTTPS 가 443 입니다. 클라이언트의 포트는 OS 가 연결마다 임시로 배정합니다. 같은 PC 에서 같은 서버로 연결을 여러 개 열어도 포트 번호로 구분됩니다.

1.2 TCP, UDP, TLS 의 역할​

정의위치
TCP연결을 만든 뒤, 데이터의 도착 여부와 순서를 확인하며 전송하는 프로토콜전송 계층
UDP연결과 확인 절차 없이 데이터를 전송하는 프로토콜전송 계층
TLS전송하는 데이터를 암호화하고 서버의 신원을 확인하는 프로토콜TCP 위, HTTP 아래

전송 계층은 IP 가 컴퓨터까지 전달한 패킷을 포트 번호로 프로그램에 넘기는 계층입니다. TCP 와 UDP 는 이 계층에서 둘 중 하나를 고르는 관계입니다. TLS 는 TCP 나 UDP 를 대체하지 않고 그 위에서 암호화와 인증을 추가합니다. 웹은 TCP 위에 TLS 를 얹어 씁니다.


2. TCP: 전달을 어떻게 보장할까​

TCP(Transmission Control Protocol)는 데이터를 보내기 전에 연결을 만들고, 보낸 데이터마다 수신 확인을 받는 프로토콜입니다. 이 방식으로 데이터의 도착 여부와 순서를 보장합니다.

2.1 연결 시작과 종료​

왼쪽 3-Way Handshake 는 클라이언트의 SYN, 서버의 SYN+ACK, 클라이언트의 ACK 순서로 끝나고 양쪽이 ESTABLISHED 가 된다. 오른쪽 4-Way Handshake 는 FIN, ACK, FIN, ACK 순서이고 클라이언트는 TIME_WAIT 에 머문 뒤 닫힌다

TCP 헤더의 플래그 세 가지를 먼저 정의합니다.

  • SYN: 연결을 요청하는 플래그입니다.
  • ACK: 데이터나 요청을 받았다는 확인 플래그입니다.
  • FIN: 연결을 종료하겠다는 플래그입니다.

연결을 만드는 3-Way Handshake 는 세 단계입니다.

  1. SYN: 클라이언트가 자기 시작 번호(seq)를 담아 연결을 요청합니다.
  2. SYN+ACK: 서버가 요청을 확인하고(ack=101 은 100번까지 받았으니 다음은 101번이라는 뜻) 자기 시작 번호를 보냅니다.
  3. ACK: 클라이언트가 서버의 시작 번호를 확인합니다. 이때부터 데이터를 보냅니다.

양쪽이 각자 시작 번호를 알리고 상대가 받았음을 확인해야 하므로 세 번이 필요합니다. 시작 번호는 연결마다 무작위로 정해집니다.

연결을 끝내는 4-Way Handshake 는 닫는 방향이 둘이라 네 번입니다. 클라이언트가 FIN 을 보내도 서버는 아직 보낼 데이터가 남았을 수 있습니다. 그럼 ACK 만 먼저 돌려주고, 다 보낸 뒤에 자기 FIN 을 보냅니다.

클라이언트는 마지막 ACK 가 유실되어 서버가 FIN 을 다시 보내는 경우에 대비해 TIME_WAIT 상태로 잠시 머뭅니다.

2.2 번호, ACK, 재전송​

보내는 쪽이 seq 1100 을 보내면 받는 쪽이 ack=101 로 답한다. seq 101200 이 유실되고 201300 만 도착하면 받는 쪽은 201300 을 보관하고 ack=101 을 다시 보낸다. 보내는 쪽이 101~200 을 재전송하면 받는 쪽이 이어 붙여 ack=301 을 보낸다

  • 번호: 보내는 데이터에 순서대로 번호(seq)를 붙입니다.
  • ACK: 받는 쪽이 ack=N 으로 N번 전까지 받았고 다음은 N번이라고 알립니다.
  • 재전송: ACK 가 제한 시간 안에 오지 않거나 같은 ack 가 여러 번 반복되면 보내는 쪽이 그 구간을 다시 보냅니다.
  • 순서 보장: 데이터가 뒤섞여 도착해도 받는 쪽이 번호로 이어 붙인 뒤 애플리케이션에 순서대로 넘깁니다.

이 밖에 받는 쪽이 처리할 수 있는 양에 맞추는 흐름 제어, 네트워크가 막히면 속도를 낮추는 혼잡 제어도 TCP 가 맡습니다. 신뢰성의 대가로 시작할 때 왕복이 필요하고, 패킷 하나가 유실되면 뒤에 도착한 데이터도 빈 구간이 채워질 때까지 기다립니다.


3. UDP: 무엇을 생략해서 빠를까​

UDP(User Datagram Protocol)는 연결을 만들지 않고 데이터를 포트로 전달하기만 하는 프로토콜입니다. 수신 확인, 재전송, 순서 맞추기를 하지 않습니다. 헤더도 8바이트로 TCP(최소 20바이트)보다 작습니다.

3.1 TCP 와 UDP 의 차이​

아무도 듣지 않는 포트로 보내면 두 프로토콜의 차이가 바로 드러납니다.

udp-vs-tcp.mjs
import dgram from 'node:dgram';
import net from 'node:net';

const udp = dgram.createSocket('udp4');
udp.send('hello', 41234, '127.0.0.1', (err) => {
console.log('UDP:', err ? err.message : '전송 성공');
udp.close();
});

net.connect(41234, '127.0.0.1').on('error', (e) => console.log('TCP:', e.code));
실행 결과
UDP: 전송 성공
TCP: ECONNREFUSED

UDP 의 전송 성공은 내보냈다는 뜻일 뿐 도착했다는 뜻이 아닙니다. TCP 는 연결 단계에서 상대에게 거절당해 바로 실패합니다.

TCPUDP
연결만든 뒤 전송없이 바로 전송
전달 확인ACK 와 재전송없음
순서번호로 보장보장 안 함

UDP 가 빠른 이유는 전송 속도 자체가 아니라 기다림이 없기 때문입니다.

3.2 언제 무엇을 쓸까​

데이터가 하나라도 빠지면 쓸 수 없으면 TCP 를 쓰고, 늦게 도착한 데이터가 쓸모없으면 UDP 를 씁니다.

프로토콜사용 예선택 이유
TCP웹 페이지, API 요청(HTTP/1.1, HTTP/2)HTML 이나 JSON 은 일부만 받으면 해석할 수 없음
TCPWebSocket 채팅HTTP 로 시작한 연결을 유지하며 메시지를 순서대로 주고받음
TCPSSH, 이메일(SMTP), 파일 전송명령, 메일, 파일 내용이 빠지거나 순서가 바뀌면 안 됨
UDPDNS 질의요청 하나와 응답 하나로 끝나서 연결을 만드는 단계가 오히려 부담
UDP실시간 음성·영상 통화재전송된 패킷은 도착했을 때 이미 재생 시점이 지났음
UDP온라인 게임의 위치 갱신최신 값이 계속 오므로 유실된 이전 값을 다시 받을 필요가 없음

4. TLS: 안전하게 보내려면​

4.1 TLS 란​

TLS(Transport Layer Security)는 TCP 연결 위에서 데이터를 암호화하고 서버의 신원을 확인하는 프로토콜입니다.

TCP 는 데이터의 도착은 보장하지만 내용을 암호화하지 않습니다. 경로 중간에서 패킷을 읽을 수 있으면 로그인 정보가 그대로 보입니다.

중간에서 가로챈 패킷
HTTP : POST /login HTTP/1.1 ... password=1234
HTTPS: 17 03 03 00 5a 8f 2c e1 b4 07 ... (암호문)

TLS 가 제공하는 세 가지 기능입니다.

기능정의막는 위협
암호화(기밀성)세션 키로 데이터를 암호문으로 바꿔 전송중간에서 내용을 읽는 것
무결성데이터마다 검증 값을 붙여 전송 중 변조를 감지중간에서 내용을 바꾸는 것
인증서버가 보낸 인증서로 접속한 서버의 신원을 확인가짜 서버에 접속하는 것

4.2 TLS Handshake 와 인증서​

브라우저가 ClientHello 로 지원하는 암호 방식과 키 재료를 보내고, 서버가 ServerHello 로 고른 방식과 키 재료를 답한다. 양쪽이 세션 키를 계산한 뒤 서버가 인증서와 Finished 를 암호화해 보내고 브라우저가 인증서를 검증한다. 브라우저의 Finished 이후 애플리케이션 데이터가 세션 키로 암호화되어 오간다

세션 키는 이 연결의 데이터를 암호화하는 데 쓰는 키입니다.

  1. Hello 교환: 사용할 암호 방식을 정하고 서로 키 재료(공개 값)를 보냅니다. 양쪽이 같은 세션 키를 계산하며 세션 키 자체는 네트워크로 전송되지 않습니다.
  2. 인증서 전달: 서버가 인증서와 서명을 보냅니다. 서명은 인증서의 공개 키와 짝인 비밀 키로 만들며, 이 서버가 그 비밀 키를 가졌다는 증거입니다.
  3. Finished: 지금까지 주고받은 Handshake 메시지가 양쪽에서 같았는지 확인합니다.
  4. 데이터 전송: 이후 모든 데이터를 세션 키로 암호화합니다.

키를 합의하는 데는 느린 비대칭 방식을 쓰고, 대량의 데이터는 빠른 대칭 방식으로 암호화합니다. TLS 1.3 은 이 과정이 왕복 1번이고 TLS 1.2 는 2번입니다.

인증서는 서버의 공개 키, 도메인 이름, 만료일, 발급한 CA 의 서명을 담은 문서입니다. CA(인증 기관)는 도메인 소유자를 확인하고 인증서에 서명하는 기관입니다. 브라우저는 OS 와 브라우저에 미리 들어 있는 신뢰 CA 목록으로 세 가지를 확인합니다. 서명이 신뢰하는 CA 로 이어지는지, 접속한 도메인과 일치하는지, 만료되지 않았는지입니다. 하나라도 어긋나면 경고 화면이 뜹니다.

curl -v 로 같은 과정을 볼 수 있습니다.

curl -v https://asap-note.pages.dev (일부)
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* subject: CN=asap-note.pages.dev
* issuer: C=US; O=Google Trust Services; CN=WE1
* SSL certificate verify ok.

4.3 HTTP 와 HTTPS 의 차이​

HTTPS 는 별개의 프로토콜이 아니라 HTTP 를 TLS 위에서 보내는 방식입니다. 요청 메시지의 모양은 그대로입니다.

HTTPHTTPS
기본 포트80443
전송 구간평문TLS 로 암호화
서버 신원확인하지 않음인증서로 확인
준비물없음CA 에서 발급한 인증서
HTTP/2, HTTP/3브라우저에서 사용 불가사용 가능

4.4 TLS 와 SSH​

둘 다 TCP 위에서 키를 합의하고 대칭 암호로 보호하는 구조는 같습니다. 서버를 믿는 방법과 쓰는 곳이 다릅니다.

TLSSSH
주 용도웹, API 등 서비스 통신 보호원격 서버 셸 접속, 파일 전송
기본 포트44322
서버를 믿는 방법CA 가 서명한 인증서첫 접속 때 호스트 키를 확인하고 known_hosts 에 저장해 이후 비교
사용자 인증보통 없음(앱이 로그인 처리)비밀번호 또는 SSH 키

5. 실제 웹 통신 과정​

5.1 HTTPS 페이지에 접속하면​

DNS 조회는 UDP 53번으로 19.5ms, TCP 연결은 왕복 1번에 5.4ms, TLS 1.3 협상은 왕복 1번에 12.6ms, 암호화된 HTTP 요청과 응답은 첫 바이트까지 122.6ms 가 걸린다

  1. DNS 조회: 도메인을 IP 주소로 바꿉니다. 짧은 질의와 응답이라 보통 UDP 를 씁니다.
  2. TCP 연결: 그 IP 의 443 포트로 3-Way Handshake 를 합니다.
  3. TLS Handshake: 인증서를 검증하고 세션 키를 만듭니다.
  4. HTTP 요청·응답: 암호화된 연결 위에서 요청을 보내고 응답을 받습니다.

curl 로 단계마다 걸린 시간을 확인할 수 있습니다.

curl -so /dev/null -w 'dns %{time_namelookup}\nconnect %{time_connect}\ntls %{time_appconnect}\nfirstbyte %{time_starttransfer}\n' https://asap-note.pages.dev
실행 결과 (초)
dns 0.019481
connect 0.024840
tls 0.037465
firstbyte 0.160090

각 값은 요청을 시작한 시점부터의 누적 시간입니다. 단계별 비용은 앞 값과의 차이입니다. TCP 는 0.024840 - 0.019481 = 약 5.4ms, TLS 는 0.037465 - 0.024840 = 약 12.6ms 입니다.

이 비용은 처음 연결할 때만 붙습니다. 같은 연결을 재사용하는 이후 요청은 4단계만 거칩니다. 서버가 멀수록 왕복 한 번이 길어지므로, 첫 바이트를 받기까지 지나는 왕복 3번(TCP, TLS, HTTP 요청)이 체감 시간이 됩니다.

5.2 한눈에 비교​

TCPUDPTLS
해결하는 문제전달 여부와 순서기다림 없는 전달도청, 변조, 사칭
시작할 때3-Way Handshake없음TLS Handshake (TCP 연결 위에서)
유실이 나면재전송그대로 둠하위 프로토콜에 따름
내용 보호없음없음암호화, 무결성, 인증