뇌절의 첫 시리즈 주제, TCP입니다. 로드맵에서 예고한 대로, 이번 글은 기본 단계의 첫 번째 글이라 아주 기초적인 질문부터 시작합니다: TCP가 정확히 뭘 하는 프로토콜인가?

TCP는 어디에 있는가

인터넷에서 데이터를 주고받을 때, 여러 계층이 각자 역할을 나눠 맡습니다. TCP/IP 4계층 모델로 보면 이렇습니다.

Application 계층 HTTP · DNS · SSH ... Transport 계층 TCP 연결지향 · 신뢰성 — 이 시리즈의 주제 UDP 비연결 · 빠름 Internet 계층 IP Link 계층 Ethernet · Wi-Fi ...
TCP는 Transport 계층에서 UDP와 나란히 동작하며, Internet 계층(IP) 위에 얹혀서 돈다.

여기서 두 가지만 기억하면 됩니다.

  1. TCP는 IP 위에서 동작한다. “TCP/IP”라는 이름 자체가 이 관계를 말해줍니다. IP는 “어디로 보낼지(주소)”만 책임지고, 그 패킷이 가는 중에 사라지든 순서가 뒤바뀌든 신경 쓰지 않습니다. 그 위에서 “확실하게, 순서대로” 보내는 역할을 TCP가 맡습니다.
  2. Transport 계층에는 TCP만 있는 게 아니다. 같은 자리에 UDP도 있습니다. 둘은 같은 문제(애플리케이션 간에 데이터를 주고받는 것)를 완전히 다른 방식으로 풉니다. 이 차이가 이 글의 핵심입니다.

“연결지향”과 “신뢰성”이 구체적으로 뭔가

TCP를 설명할 때 항상 따라붙는 두 단어가 “연결지향(connection-oriented)”과 “신뢰성 있는(reliable)”입니다. 각각 구체적으로 무슨 뜻인지 뜯어보겠습니다.

  • 연결지향: 데이터를 보내기 전에 먼저 양쪽이 “연결”이라는 상태를 만듭니다. 이 상태가 있어야만 데이터를 주고받을 수 있고, 다 끝나면 명시적으로 연결을 끊습니다. (연결을 어떻게 맺는지는 3편에서 다룹니다.)
  • 신뢰성: 보낸 데이터가 상대방에게 순서대로, 빠짐없이 도착했다는 걸 보장합니다. 중간에 유실되면 다시 보내고, 순서가 뒤바뀌어 도착해도 원래 순서로 재조립해줍니다. (구체적인 방법은 4~5편에서 다룹니다.)

UDP는 이 둘 다 하지 않습니다. 연결이라는 개념 자체가 없고, 보낸 데이터가 도착했는지도 UDP 스스로는 신경 쓰지 않습니다. 그림으로 비교하면 이렇습니다.

TCP — 연결지향 Client Server 연결을 맺고 유지하며 데이터 교환 UDP — 비연결 Client Server 그때그때 독립적으로 전송 (연결 없음)
TCP는 연결을 유지한 채로 데이터를 주고받고, UDP는 연결이라는 상태 없이 패킷을 독립적으로 보낸다.

UDP 쪽 화살표 3개가 서로 이어져 있지 않다는 점이 중요합니다. 각 패킷은 서로 아무 관계가 없습니다. 하나가 중간에 사라져도 UDP는 그걸 모르고, 순서가 뒤바뀌어 도착해도 신경 쓰지 않습니다. 그 대신 “연결을 맺고 유지하는” 오버헤드가 없어서 더 가볍고 빠릅니다.

TCP vs UDP

  TCP UDP
연결 연결지향 (핸드셰이크 필요) 비연결
신뢰성 순서 보장, 유실 시 재전송 보장 없음
속도 상대적으로 느림 (연결 유지·재전송 비용) 빠름
오버헤드 큼 (헤더 20바이트, 상태 관리) 작음 (헤더 8바이트)
대표 사용처 웹(HTTP), 파일 전송, 이메일 — “틀리면 안 되는” 데이터 실시간 스트리밍, 온라인 게임, DNS — “늦으면 의미 없는” 데이터

이 표에서 가장 중요한 건 “TCP가 항상 더 좋다”가 아니라는 겁니다. 실시간 음성 통화에서는 0.5초 전 패킷이 지금 도착해서 재생되는 것보다, 그냥 버리고 최신 패킷을 트는 게 낫습니다. TCP가 유실된 패킷을 재전송하려고 애쓰는 동안 통화는 이미 끊긴 것처럼 느껴집니다. 그래서 이런 경우엔 UDP를 씁니다. 반대로 파일 하나를 내려받는데 중간 바이트 몇 개가 빠지면 파일 자체가 깨지므로, 이런 경우엔 반드시 TCP를 씁니다.

이 시리즈에서 쓸 용어

앞으로 자주 나올 단어 세 개를 미리 정리합니다.

  • 세그먼트(segment): TCP가 주고받는 데이터 단위. (IP 계층에서는 이걸 “패킷”, Link 계층에서는 “프레임”이라고 부릅니다. 같은 데이터를 계층마다 다르게 부르는 것뿐입니다.)
  • 연결(connection): 3-way handshake로 맺어지고 4-way handshake로 끊어지는, 두 endpoint 사이의 상태. TCP의 모든 동작은 이 연결이 있다는 걸 전제로 합니다.
  • 스트림(stream): TCP가 애플리케이션에 제공하는 추상화. 애플리케이션 입장에서 TCP는 “세그먼트를 여러 개 주고받는 것”이 아니라 “끊김 없는 바이트의 흐름”처럼 보입니다. 이 스트림 추상화 뒤에서 세그먼트 분할, 재조립, 재전송이 전부 숨겨져 있습니다.

다음 글

지금까지는 “TCP가 뭘 하는가”를 큰 그림으로만 봤습니다. 다음 글에서는 “같은 컴퓨터에서 여러 프로그램이 동시에 TCP를 쓰면 어떻게 구분하는가” — 포트와 소켓 이야기로 넘어갑니다.