TCP와 UDP 전송 프로토콜
Series: 네트워크
네트워크contains 2
들어가며
네트워크를 통해 데이터를 주고받는다는 것은 생각보다 복잡한 과정이다. 우리가 브라우저에서 웹 페이지를 열거나, 유튜브 영상을 보거나, 온라인 게임을 할 때는 단순히 '요청 → 응답' 정도로만 느껴지지만, 그 내부에서는 다양한 계층과 규칙들이 작동하고 있다. 그중에서도 전송 계층(Transport Layer)은 매우 중요한 역할을 담당한다. 이 계층은 단순히 데이터를 보내는 것이 아니라, '데이터를 어떤 방식으로 전달할 것인지?'를 결정한다. 그리고 이 역할을 수행하는 대표적인 프로토콜이 바로 TCP와 UDP이다. TCP와 UDP는 모두 데이터를 전달하기 위한 프로토콜이지만, 설계 철학 자체가 다르다. TCP는 정확하게 보내는 것에 집중하고, UDP는 빠르게 보내는 것에 집중한다. 이 차이를 이해하는 것이 전송 프로토콜을 이해하는 핵심이다.
1. 전송 계층(Transport Layer)
전송 계층은 OSI 7계층 중 4계층에 해당하며, 애플리케이션에서 만들어진 데이터를 실제로 네트워크를 통해 전달하기 직전에 다루는 계층이다. 이 계층에서 중요한 점은, 단순히 데이터를 보내는 것이 아니라 데이터 전달의 품질을 관리한다는 것이다. 예를 들어 다음과 같은 문제들을 생각해볼 수 있다.
- 데이터가 너무 크면 어떻게 나눌 것인가?
- 여러 개의 데이터가 순서대로 도착하지 않으면 어떻게 할 것인가?
- 중간에 데이터가 유실되면 어떻게 처리할 것인가?
- 수신 측이 데이터를 처리할 수 있는 속도를 초과하면 어떻게 할 것인가?
이러한 문제들을 해결하는 것이 전송 계층의 역할이다. 그리고 이 문제를 해결하는 방식에 따라 TCP와 UDP라는 두 가지 프로토콜이 등장하게 된다.
2. TCP: 신뢰성을 선택한 프로토콜
TCP는 데이터를 전달할 때 가장 중요하게 생각하는 것이 신뢰성이다. 즉, 데이터가 반드시 정확하게 도착해야 한다는 것을 전제로 설계된 프로토콜이다. 이러한 탓에 주로 웹 요청(HTTP, HTTPS), 파일 다운로드, 결제 시스템과 같은 상황에서 사용된다.
2.1. 3-Way Handshake
TCP는 데이터를 바로 전송하지 않는다. 그 전에 반드시 상대방과의 연결 상태를 먼저 확인하는 과정을 거친다. 이 과정을 3-Way Handshake라고 한다. 이 과정을 단순히 '연결을 만든다'라고만 이해하면 다소 추상적으로 느껴질 수 있다. 실제로는 양쪽이 서로 통신 가능한 상태인지, 그리고 동일한 기준으로 데이터를 주고받을 준비가 되었는지를 확인하는 절차라고 보는 것이 더 정확하다.
sequenceDiagram
participant Client
participant Server
Client->>Server: SYN
Server-->>Client: SYN + ACK
Client->>Server: ACK먼저 클라이언트가 서버에게 SYN이라는 신호를 보낸다. 이 메시지는 단순히 연결하고 싶다는 의미만 담고 있는 것이 아니라, 이후 통신에 사용할 초기 정보까지 함께 전달한다. 예를 들어, 데이터를 어떤 순서로 주고받을 것인지에 대한 기준이 되는 시퀀스 번호도 이 단계에서 포함된다. 즉, 단순 요청이라기보다 이런 방식으로 통신을 시작하고 싶다는 제안에 가깝다. 서버는 이 요청을 받으면, 자신의 상태를 확인한 뒤 응답을 보낸다. 이때 SYN과 ACK를 함께 보내는데, ACK는 클라이언트의 요청을 정상적으로 받았다는 의미이고, SYN은 서버 역시 통신을 시작할 준비가 되었음을 나타낸다. 다시 말해 서버는 '너의 요청은 잘 받았고, 나도 통신할 준비가 되어 있다'라는 메시지를 동시에 전달하는 것이다. 마지막으로 클라이언트는 서버의 응답을 확인한 뒤 ACK를 다시 보낸다. 이 단계까지 완료되면, 클라이언트와 서버는 서로가 통신 가능한 상태임을 확실하게 검증하게 되고, 그 이후에야 비로소 실제 데이터 전송이 시작된다.
이 과정을 굳이 세 단계로 나누는 이유는 네트워크 환경이 항상 안정적이지 않기 때문이다. 단순히 한 번의 요청과 응답만으로 연결을 시작한다면, 중간에 메시지가 유실되거나 상대방이 준비되지 않은 상태일 때도 통신이 시작될 수 있다. 그렇게 되면 데이터가 제대로 전달되지 않거나, 서로 다른 상태를 기준으로 통신이 진행되어 오류가 발생할 수 있다. 따라서 TCP는 데이터를 보내기 전에 정말로 통신을 시작해도 되는 상태인지를 양방향으로 확인하는 과정을 거친다. 이 과정이 바로 3-Way Handshake이며, TCP가 신뢰성 있는 통신을 제공할 수 있는 이유 중 하나이다. 결국 이 과정은 단순한 연결 절차가 아니라, 안정적인 데이터 전송을 위한 사전 검증 단계라고 볼 수 있다. TCP는 처음부터 이러한 검증 과정을 거침으로써, 이후 데이터 전송 과정에서 발생할 수 있는 문제를 최대한 줄이도록 설계된 프로토콜이다.
2.2. 응답(ACK)
TCP가 신뢰성 있는 통신이라고 불리는 이유는, 단순히 데이터를 보내는 데서 끝나지 않고 데이터가 제대로 도착했는지까지 확인하는 구조를 가지고 있기 때문이다. TCP는 데이터를 한 번에 통째로 보내지 않는다. 네트워크 환경에서는 큰 데이터를 한 번에 보내는 것이 비효율적일 뿐만 아니라, 중간에 일부가 손실될 경우 전체를 다시 보내야 하는 문제가 발생한다. 그래서 TCP는 데이터를 일정한 크기의 작은 단위(세그먼트)로 나눈다. 그리고 각 세그먼트에는 순서를 나타내는 번호(Sequence Number)가 붙는다. 이 번호 덕분에 수신 측은 데이터를 받았을 때 순서가 뒤섞이더라도 올바르게 재조립할 수 있다. 이제 데이터를 보내는 과정에서 핵심이 되는 개념이 등장한다. 바로 ACK(응답)이다.
sequenceDiagram
participant Client
participant Server
Client->>Server: 데이터 1
Server-->>Client: ACK
Client->>Server: 데이터 2
Server-->>Client: ACKTCP에서는 데이터를 보낸 쪽이 '보냈다'로 끝나는 것이 아니라, 상대방이 '잘 받았다'라고 확인해주는 과정까지 포함된다. 수신 측은 데이터를 정상적으로 받으면 ACK 신호를 보내고, 송신 측은 이 ACK를 통해 데이터가 제대로 전달되었음을 확인한다.
2.3. 재전송(Retransmission)
만약 ACK가 오지 않는다면 어떻게 될까? TCP는 일정 시간 동안 ACK를 기다리다가, 응답이 오지 않으면 해당 데이터가 전달되지 않았다고 판단한다. 그리고 동일한 데이터를 다시 전송한다. 이 과정을 재전송(Retransmission)이라고 한다. 이 구조 덕분에 TCP는 단순히 데이터를 보내는 것이 아니라, 데이터가 실제로 도착했는지까지 책임지는 방식을 가지게 된다.
2.4. 순서 보장
또한 TCP는 순서도 보장한다. 예를 들어 데이터 1, 2, 3을 보냈는데 네트워크 상황 때문에 2가 먼저 도착하고 1이 나중에 도착했다고 해보자. 이 경우 수신 측은 순서 번호를 기반으로 데이터를 올바르게 정렬한 뒤 애플리케이션에 전달한다. 즉, 애플리케이션 입장에서는 항상 올바른 순서의 데이터만 받게 된다. 정리해보면 TCP는 다음과 같은 방식으로 신뢰성을 확보한다.
- 데이터를 작은 단위로 나누어 전송한다
- 각 데이터에 순서를 부여한다
- 수신 측으로부터 ACK를 받아 전달 여부를 확인한다
- 문제가 발생하면 재전송한다
이러한 과정을 거치기 때문에 TCP는 데이터 손실을 최소화하고, 순서를 보장하며, 안정적인 통신을 제공할 수 있다. 물론 이 모든 과정은 비용을 동반한다. 데이터를 보낼 때마다 확인을 해야 하고, 문제가 생기면 다시 보내야 하기 때문에 속도는 상대적으로 느려질 수밖에 없다. 하지만 그 대신 데이터는 반드시 정확하게 도착한다는 강력한 보장을 제공한다. 그래서 TCP는 결국 다음과 같은 철학을 가진 프로토콜이라고 볼 수 있다.
느리더라도, 확실하게 전달하자
3. UDP: 속도를 선택한 프로토콜
UDP는 TCP와는 전혀 다른 방향에서 출발한 프로토콜이다. TCP가 '데이터는 반드시 정확하게 도착해야 한다'는 전제를 바탕으로 설계되었다면, UDP는 그와 반대로 '가능한 한 빠르게 전달하는 것이 더 중요하다'는 관점에서 만들어졌다. 이 차이는 단순한 구현 방식의 차이가 아니라, 문제를 바라보는 방식 자체의 차이라고 볼 수 있다. 어떤 상황에서는 데이터가 완벽하게 전달되는 것이 중요하지만, 어떤 상황에서는 약간의 손실이 있더라도 지연 없이 전달되는 것이 훨씬 더 중요하기 때문이다. UDP는 바로 후자의 상황에 초점을 맞춘 프로토콜이다. 이러한 철학 덕분에 UDP는 실시간 스트리밍, 온라인 게임 등 실시간성이 중요한 다양한 서비스에서 핵심적인 역할을 수행하고 있다.
3.1. 연결 없이 바로 전송
UDP의 가장 큰 특징은 TCP처럼 사전에 연결을 설정하지 않는다는 점이다. TCP는 데이터를 보내기 전에 3-Way Handshake를 통해 서로 통신 가능한 상태인지 확인하지만, UDP는 이러한 과정을 완전히 생략한다.
sequenceDiagram
participant Client
participant Server
Client->>Server: 데이터 전송이 흐름을 보면 알 수 있듯이, UDP는 상대방의 상태를 확인하지 않고 데이터를 바로 전송한다. 이때 중요한 점은, 이 과정에서 어떤 형태의 확인 절차도 존재하지 않는다는 것이다. 예를 들어 TCP에서는 데이터를 보내면 상대방이 '잘 받았다'라는 ACK를 보내지만, UDP에서는 그런 과정이 없다. 데이터를 보낸 이후에 상대방이 실제로 데이터를 받았는지, 중간에 유실되었는지, 혹은 순서가 뒤바뀌었는지에 대해서 UDP는 전혀 관여하지 않는다. 이러한 특성 때문에 UDP는 다음과 같은 특징을 가지게 된다.
- 상대방이 통신 가능한 상태인지 확인하지 않는다
- 데이터가 정상적으로 도착했는지 확인하지 않는다
- 데이터가 유실되더라도 재전송하지 않는다
즉, UDP는 데이터를 전달하는 과정에서 발생할 수 있는 다양한 문제들을 의도적으로 신경 쓰지 않는 구조를 가진다. 대신 그만큼 불필요한 과정이 줄어들기 때문에, 매우 빠른 속도로 데이터를 전송할 수 있다.
3.2. 왜 이런 설계를 했을까?
처음 보면 UDP는 상당히 불완전한 프로토콜처럼 느껴질 수 있다. '확인도 안 하고, 재전송도 안 하면 이걸 왜 쓰지?'라는 생각이 들 수 있다. 하지만 실제로는 UDP가 필요한 상황이 분명히 존재한다. 대표적인 예가 실시간 영상 스트리밍이다. 영상을 재생할 때는 수많은 프레임이 연속적으로 전송된다. 이때 특정 프레임 하나가 네트워크 문제로 유실된다고 해도, 사용자는 거의 인지하지 못하는 경우가 많다. 하지만 만약 그 프레임을 다시 받기 위해 재전송을 기다린다면, 영상이 끊기거나 버퍼링이 발생하게 된다. 사용자 경험 측면에서는 이쪽이 훨씬 더 큰 문제다. 예를 들어 이런 상황을 생각해볼 수 있다.
- 프레임 하나가 유실됨 → 거의 티가 나지 않음
- 재전송을 기다림 → 영상이 멈춤
이 경우에는 정확성보다 연속성이 더 중요하다. 그래서 UDP는 유실된 데이터를 굳이 다시 받으려고 하지 않고, 그냥 다음 데이터를 받아 계속 진행한다. 이러한 특성은 음성 통화나 온라인 게임에서도 동일하게 적용된다. 음성 통화에서 아주 짧은 구간의 데이터가 유실되더라도 대화는 계속 이어질 수 있지만, 통신이 지연되면 대화 자체가 어려워진다. 온라인 게임에서도 마찬가지로, 약간의 데이터 손실보다 지연(latency)이 훨씬 더 큰 영향을 미친다. 결국 UDP는 이렇게 생각하는 프로토콜이다.
모든 데이터를 완벽하게 전달하는 것보다, 지금 이 순간의 흐름을 유지하는 것이 더 중요하다
4. TCP vs UDP
TCP와 UDP의 차이를 한 문장으로 정리하면 결국 이것이다.
데이터를 정확하게 전달할 것인가, 아니면 빠르게 전달할 것인가
이 두 프로토콜은 같은 문제(데이터 전송)를 해결하지만, 전혀 다른 기준으로 설계되었기 때문에 동작 방식과 특징에서도 큰 차이를 보인다.
| 구분 | TCP | UDP |
|---|---|---|
| 철학 | 정확성 | 속도 |
| 셩격 | 신뢰성 | 연속성 |
| 연결 | 있음 (연결 기반) | 없음 (비연결형) |
| 재전송 | 있음 | 없음 |
| 순서 보장 | 있음 | 없음 |
| 속도 | 상대적으로 느림 | 매우 빠름 |
| 오버헤드 | 큼 | 작음 |
이 표를 단순히 외우기보다는, 각각이 왜 이런 특징을 가지게 되었는지를 이해하는 것이 중요하다. TCP는 데이터를 보내기 전에 연결을 맺고, 데이터를 나누어 전송하며, 각 데이터가 제대로 도착했는지 확인하고, 문제가 생기면 재전송까지 수행한다. 이 과정 덕분에 데이터의 정확성과 순서를 보장할 수 있지만, 그만큼 처리 과정이 많아져 속도는 느려질 수밖에 없다.
반면 UDP는 이러한 과정들을 대부분 생략한다. 연결도 맺지 않고, 데이터가 도착했는지도 확인하지 않으며, 문제가 생겨도 다시 보내지 않는다. 대신 불필요한 절차가 없기 때문에 매우 빠르게 데이터를 전송할 수 있다. 즉, 두 프로토콜은 좋고 나쁨의 문제가 아니라, 어떤 상황에 더 적합한가의 문제라고 볼 수 있다.
5. HTTP/3의 등장
실제 서비스에서는 TCP와 UDP가 경쟁 관계라기보다, 서로 다른 상황에서 자연스럽게 선택되는 도구에 가깝다. 예를 들어 우리가 웹 브라우저로 어떤 페이지를 요청하는 상황을 생각해보자. 이때는 HTML, CSS, JavaScript와 같은 리소스가 정확하게 전달되어야 한다. 데이터가 하나라도 손상되거나 빠지면 페이지가 정상적으로 렌더링되지 않을 수 있기 때문에, 이 경우에는 TCP 기반의 HTTP/HTTPS 프로토콜이 사용된다.
반대로 유튜브와 같은 영상 스트리밍 서비스를 보면, 상황이 조금 다르다. 영상은 초당 수십 개의 프레임으로 구성되는데, 그 중 일부 프레임이 유실되더라도 사용자는 큰 차이를 느끼지 못하는 경우가 많다. 하지만 재전송을 기다리게 되면 영상이 끊기거나 버퍼링이 발생하게 된다. 이런 환경에서는 약간의 데이터 손실을 감수하더라도 빠르게 데이터를 전달하는 것이 더 중요하기 때문에 UDP 기반의 전송 방식이 사용된다. 온라인 게임 역시 비슷한 특성을 가진다. 캐릭터의 위치 정보나 상태 정보는 매우 빠르게 전달되어야 하며, 약간의 데이터 손실보다 지연이 훨씬 더 큰 문제를 만든다. 그래서 게임 서버는 UDP를 활용하여 빠른 응답성을 유지한다.
최근에는 이러한 두 가지 특성을 모두 활용하려는 시도도 등장하고 있다. 대표적인 예가 HTTP/3이다. HTTP/3는 UDP를 기반으로 동작하지만, 그 위에 신뢰성을 보장하기 위한 메커니즘을 추가하여 TCP의 장점을 일부 가져온다. 즉, 단순히 TCP나 UDP 중 하나를 선택하는 것이 아니라, 필요한 특성을 조합하여 새로운 방식으로 발전하고 있는 것이다. 중요한 것은 어떤 프로토콜이 더 좋은지 비교하는 것이 아니라, 현재 서비스가 요구하는 것이 정확성인지, 속도인지를 판단하는 것이다. 이 기준에 따라 TCP와 UDP는 자연스럽게 선택되고, 때로는 함께 사용되면서 네트워크 통신을 구성하게 된다.
마치며
TCP와 UDP는 단순히 다른 프로토콜이 아니라, 서로 다른 문제를 해결하기 위해 만들어진 서로 다른 접근 방식이다. TCP는 데이터가 반드시 정확해야 한다는 문제를 해결하기 위해 만들어졌고, UDP는 빠르게 전달해야 한다는 문제를 해결하기 위해 만들어졌다. 결국 중요한 것은 어떤 프로토콜이 더 좋은가가 아니라, 지금 이 상황에서 무엇이 더 중요한가를 판단하는 것이다. 이 기준을 이해하면, 네트워크 통신을 단순한 기술이 아니라 의도와 선택의 결과로 바라볼 수 있게 된다.