학습 공간 개념 · 판단 · 실험

Frontend Performance Lab

네트워크

TCP 바이트 스트림과 UDP 데이터그램

전송 계층이 바이트나 패킷을 전달해 주는 보장과 상위 애플리케이션이 메시지를 처리했다는 보장은 서로 다릅니다.

이럴 때 필요해요

소켓 버퍼 읽기, 네트워크 끊김 후의 재시도, 그리고 실시간 통신 프로토콜 선택을 올바르게 설계하기 위해 필요합니다.

어떻게 동작하나요?

TCP를 흔히 '신뢰성 있는 프로토콜'이라고 부르는 이유는 바이트마다 순서 번호(Sequence Number)를 매기고 확인 응답(ACK)과 재전송을 통해 보낸 순서 그대로 빠짐없이 바이트 스트림(Byte Stream)을 전달해 주기 때문입니다. 이때 주의할 점은 TCP가 메시지 덩어리의 경계를 기억해 주지 않는다는 것입니다. 송신 측이 5바이트와 3바이트를 연달아 보냈더라도 수신 측 소켓에서는 한 번에 8바이트로 합쳐 읽히거나 2바이트씩 나뉘어 읽힐 수 있어서, HTTP처럼 길이를 적거나 구분자를 두는 메시지 프레이밍(Framing)이 상위 계층에 꼭 필요합니다.

또한 TCP는 수신자의 버퍼 여유에 맞추는 흐름 제어와 네트워크 혼잡을 피하는 혼잡 제어를 수행하지만, 커널이 보낸 TCP ACK는 '상대방 운영체제 수신 버퍼에 바이트가 도착했다'는 뜻일 뿐 '서버 애플리케이션이 DB에 주문을 저장하고 응답을 만들었다'는 뜻이 아닙니다. 만약 서버가 결제 처리를 마친 직후 응답을 보내기 전에 네트워크가 끊기면 TCP만으로는 성공 여부를 알 수 없으므로 애플리케이션 차원의 상태 조회와 멱등 재시도 설계가 필요합니다.

반면 UDP는 연결 수립 과정 없이 애플리케이션이 넘긴 메시지 경계(데이터그램)를 그대로 전달합니다. 재전송이나 순서 정렬을 자체 제공하지 않는 대신, 앞선 패킷 하나가 유실되었다고 이미 도착한 뒤쪽 데이터 전달까지 모두 멈추는 TCP의 Head-of-Line Blocking이 없습니다. 그래서 실시간 화상회의나 게임, 혹은 UDP 위에 스트림별 독립 재전송과 TLS 보안을 직접 구현한 QUIC(HTTP/3)에서는 UDP를 기반으로 삼습니다.

코드 예제

동작을 설명하는 읽기 전용 예제입니다.

example.txt
보내기: [길이=5][hello][길이=3][bye]
읽기 1: [길이=5][he]
읽기 2: [llo][길이=3][bye]
수신 버퍼: 길이가 충분해질 때까지 보관한 후 프레임 분리
text · 읽기 전용4줄

TCP 바이트 스트림에서는 보낸 두 메시지가 수신 측 read() 호출 시 임의의 위치에서 쪼개지거나 합쳐질 수 있습니다. 따라서 길이 헤더가 온전히 모일 때까지 수신 버퍼에 담아 두었다가 프레임 단위로 잘라내는 파서가 필요합니다.

자주 헷갈리는 포인트

  • TCP 계층의 수신 확인(ACK)을 서버 비즈니스 로직(DB 저장·결제 완료)의 성공 확인과 같은 것으로 취급하면 안 됩니다.
  • UDP는 아무런 제어가 없으니 언제나 무조건 빠르고, 신뢰성이나 보안이 필요한 곳에는 절대 쓸 수 없다고 단정하면 안 됩니다.

내 말로 설명해 보기

서버가 주문을 DB에 저장한 직후 응답 패킷을 보내기 전에 네트워크 연결이 끊어졌다면, TCP의 재전송 기능만으로 클라이언트의 재요청 중복 주문을 막을 수 있을까요?

함께 읽으면 좋은 개념

관련 면접 질문 3개

TCP는 구체적으로 무엇을 신뢰성 있게 전달하며, 반대로 무엇까지는 보장하지 않나요?

TCP는 순서 번호, 확인 응답(ACK), 재전송, 중복 제거를 통해 보낸 순서대로 바이트 스트림을 전달하고, 흐름 제어와 혼잡 제어로 수신자와 네트워크 부담을 조절합니다. 하지만 바이트 스트림에는 메시지 경계가 없으며, 연결이 영원히 유지된다거나 서버의 비즈니스 로직이 정확히 한 번만 실행되었다는 사실까지는 보장하지 않습니다. 따라서 메시지 경계 구분(프레이밍)과 중복 요청 방지는 HTTP나 애플리케이션 계층에서 직접 설계해야 합니다.

꼬리질문과 참고자료 →

TCP 연결 수립(3-way)과 연결 종료(4-way)는 왜 서로 다른 단계로 진행되나요?

일반적인 TCP 연결 수립은 SYN, SYN+ACK, ACK의 3단계로 양쪽의 초기 순서 번호와 송수신 준비 상태를 한 번에 확인합니다. 반면 TCP는 양방향 독립 스트림이므로 연결을 닫을 때는 한쪽이 먼저 FIN을 보내도 반대쪽은 아직 보낼 데이터가 남아 있을 수 있어 각 방향이 FIN과 ACK를 독립적으로 주고받는 4단계 흐름을 갖습니다. 마지막에 남는 TIME_WAIT 상태는 네트워크에 지연된 이전 세그먼트가 새 연결에 섞이지 않도록 막고 마지막 ACK 재전송을 돕습니다.

꼬리질문과 참고자료 →

TCP와 UDP는 어떤 차이가 있으며 서비스 요구사항에 따라 어떻게 선택하나요?

TCP는 연결 기반으로 순서가 보장되는 신뢰성 있는 바이트 스트림을 제공하고, UDP는 연결 수립 없이 메시지 경계가 유지되는 데이터그램을 가볍게 전달합니다. UDP 자체는 순서 보장이나 재전송을 제공하지 않지만, 앞선 패킷 손실 때문에 뒤 패킷 전달까지 막히는 TCP의 Head-of-Line Blocking이 없습니다. 따라서 실시간 미디어처럼 오래된 데이터 재전송보다 지연 최소화가 중요할 때 손실·혼잡 대응과 함께 UDP를 쓰거나, UDP 위에 신뢰성과 보안을 구현한 QUIC(HTTP/3)을 선택합니다.

꼬리질문과 참고자료 →

공식 참고 자료

← 네트워크