C++, CS

[Network] TCP와 UDP 차이, Socket 통신 흐름 정리

dhlee-dev 2026. 6. 3. 17:07

최근 언리얼 엔진의 RPC, Replication 같은 네트워크 기능을 이용해
멀티플레이 게임 제작을 배우고 있다.

언리얼 엔진은 멀티플레이를 위한 기능을 많이 제공해주지만,
이 기능들을 제대로 활용하려면 기본적인 네트워크 개념도 어느 정도 알아야 한다고 생각한다.

예를 들어 서버와 클라이언트가 데이터를 어떻게 주고받는지,
TCP와 UDP는 어떤 차이가 있는지, 게임에서는 왜 UDP를 자주 사용하는지 같은 내용들이
언리얼 네트워크 기능을 이해하는 데도 도움이 될 것 같았다.

그래서 이번 글에서는 네트워크에서 데이터를 주고받기 위한 기본 규칙인 프로토콜부터 간단히 정리하고,
그다음 TCP와 UDP의 차이, 그리고 Socket 통신 흐름에 대해 정리해보려고 한다.


프로토콜이란?

프로토콜은 데이터를 주고받기 위해 사전에 합의한 통신 규칙이다.
프로토콜에는 다음과 같은 규칙이 포함될 수 있다.

  • 데이터 형식
  • 전송 순서
  • 오류 처리 방식
  • 재전송 여부
  • 연결 방식

즉, 프로토콜은 네트워크에서 통신하기 위한 약속이라고 볼 수 있다.


TCP/IP 4계층

TCP와 UDP를 이해하려면 먼저 TCP/IP 4계층에서 이들이 어디에 위치하는지 간단히 볼 필요가 있다.
TCP/IP 4계층은 보통 다음과 같이 나눌 수 있다.

계층 역할 예시
네트워크 액세스 계층 같은 네트워크 내에서 실제 데이터 전달 Ethernet, Wi-Fi, MAC 주소
인터넷 계층 서로 다른 네트워크 간 패킷 전달 IP, ICMP
전송 계층 프로세스 간 데이터 전송 방식 담당 TCP, UDP
응용 계층 사용자가 실제로 사용하는 서비스 프로토콜 HTTP, HTTPS, FTP, DNS

TCP와 UDP는 위의 계층 구조에서 전송 계층에 속한다.

전송 계층은 단순히 컴퓨터에서 컴퓨터로 데이터를 보내는 것을 넘어,
어떤 프로세스에게 데이터를 전달할 것인지와 어떤 방식으로 데이터를 전송할 것인지를 담당한다.


IP 주소와 MAC 주소

네트워크 통신에서는 IP 주소와 MAC 주소가 함께 사용된다.

IP 주소는 네트워크 상의 호스트, 즉 컴퓨터를 구분하기 위한 주소이다.
반면 MAC 주소는 같은 네트워크 안에서 실제로 데이터를 전달할 다음 장비를 찾는 데 사용된다.

만약 목적지가 같은 네트워크 안에 있다면 목적지 장비의 MAC 주소로 데이터를 전달한다.
하지만 목적지가 다른 네트워크에 있다면 일단 해당 네트워크로 가기 위한 라우터의 MAC 주소로 데이터를 보낸다.

즉, IP 주소는 최종 목적지를 찾기 위한 주소에 가깝고,
MAC 주소는 현재 네트워크 구간에서 다음에 전달할 장비를 찾기 위한 주소라고 볼 수 있다.


TCP란?

TCP(Transmission Control Protocol)는 신뢰성 있는 연결형 통신을 제공한다.

통신을 시작하기 전에 3-way handshake를 통해
서로 연결 가능한 상태인지 확인하고, 연결이 만들어진 뒤 데이터를 주고받는다.

TCP의 특징은 다음과 같다.

  • 연결형 통신이다.
  • 통신 전에 3-way handshake를 수행한다.
  • 데이터를 순서가 있는 바이트 스트림으로 전달한다.
  • 데이터 손실이 발생하면 재전송한다.
  • 수신 측에서 데이터 순서를 보장받을 수 있다.
  • 신뢰성이 중요한 통신에 사용된다.
  • 기본적으로 1:1 통신이다.

TCP는 데이터의 신뢰성이 중요한 상황에서 사용하기 좋다.


TCP는 바이트 스트림 방식이다

TCP는 데이터를 메시지 단위가 아니라 순서가 있는 바이트 스트림으로 전달한다.

즉, 보내는 쪽에서 여러 번 나누어 보낸 데이터가
받는 쪽에서 반드시 같은 단위로 나뉘어 도착한다고 보장되지 않는다.

예를 들어 송신 측에서 다음과 같이 보냈다고 해보자.

send("Hello")
send("World")

수신 측에서는 다음처럼 받을 수도 있다.

recv("HelloWorld")

또는 이렇게 나뉘어 받을 수도 있다.

recv("Hel")
recv("loWorld")

따라서 TCP를 사용할 때는 수신 측에서 메시지의 경계를 직접 구분해야 한다.
예를 들어 메시지 앞에 길이를 붙이거나 특정 구분자를 사용하는 방식이 필요할 수 있다.


UDP란?

UDP(User Datagram Protocol)는 빠르고 단순한 비연결형 통신을 제공한다.
TCP와 달리 통신 전에 연결을 확인하는 과정이 없다.

데이터를 보낼 때마다 목적지 주소를 지정해서 전송하며,
상대가 데이터를 받았는지, 순서대로 도착했는지는 기본적으로 보장하지 않는다.

UDP의 특징은 다음과 같다.

  • 비연결형 통신이다.
  • 통신 전에 연결 확인 과정을 거치지 않는다.
  • 데이터를 datagram, 즉 메시지 단위로 전송한다.
  • 데이터 순서를 보장하지 않는다.
  • 데이터 전달을 보장하지 않는다.
  • 기본적으로 손실된 데이터를 재전송하지 않는다.
  • TCP보다 지연이 낮은 편이다.
  • 멀티캐스트 / 브로드캐스트가 가능하다.

UDP는 신뢰성보다는 속도나 낮은 지연이 중요한 상황에서 사용하기 좋다.


UDP는 메시지 단위로 전송한다

UDP는 TCP와 달리 데이터를 메시지 단위로 전송한다.

송신 측에서 하나의 datagram으로 보낸 데이터는 수신 측에서도 하나의 datagram 단위로 처리된다.
따라서 TCP처럼 수신 측에서 메시지 경계를 직접 구분해야 하는 부담은 상대적으로 적다.

하지만 UDP는 데이터 손실이나 순서 보장을 기본적으로 처리해주지 않는다.

그래서 중요한 데이터라면 애플리케이션 레벨에서 재전송, 순서 번호, 확인 응답 같은 처리를 직접 구현해야 할 수 있다.


TCP와 UDP 비교

TCP와 UDP를 비교하면 다음과 같다.

구분 TCP UDP
통신 방식 연결형 비연결형
연결 확인 3-way handshake 수행 연결 확인 과정 없음
데이터 단위 바이트 스트림 Datagram / 메시지
순서 보장 보장함 보장하지 않음
손실 처리 재전송 기본적으로 재전송하지 않음
신뢰성 높음 낮음
속도 / 지연 상대적으로 느림 상대적으로 빠름
일반적인 사용 예시 웹 통신, 이메일, 파일 전송 스트리밍, 음성 통화, 실시간 데이터 전송

일반적으로 TCP는 데이터의 순서와 전달 보장이 중요한 통신에 적합하고,
UDP는 일부 데이터가 손실되더라도 빠른 전송과 낮은 지연이 중요한 통신에 적합하다.


Socket이란?

Socket은 네트워크 통신의 끝점이다.
프로그램이 네트워크를 통해 데이터를 주고받기 위해 사용하는 통로라고 볼 수 있다.

응용 프로그램은 직접 TCP/IP 내부 동작을 모두 다루는 것이 아니라,
운영체제가 제공하는 Socket API를 사용해 데이터를 송수신한다.

즉, Socket API는 응용 프로그램이 운영체제의 네트워크 기능을 사용할 수 있게 해주는 인터페이스이다.

운영체제는 소켓에 연결된 IP 주소, 포트 번호, 프로토콜 정보를 바탕으로
수신된 데이터를 적절한 프로세스에 전달한다.


네트워크 통신 대상을 구분하는 방법

네트워크 통신 대상은 보통 다음 정보로 구분할 수 있다.

  • IP 주소
  • 포트 번호
  • 프로토콜

예를 들어 로컬 테스트에서 자기 자신을 가리키는 루프백 주소인 127.0.0.1을 사용한다고 해보자.

127.0.0.1:5000 TCP
127.0.0.1:5000 UDP

두 주소는 IP와 포트 번호가 같지만 사용하는 프로토콜이 다르기 때문에 서로 다른 통신으로 구분된다.
여기서 포트 번호는 해당 컴퓨터 안에서 어떤 프로그램, 어떤 프로세스와 통신할지를 구분하기 위한 번호이다.

즉, 소켓 통신에서는 단순히 IP 주소만 보는 것이 아니라
IP 주소, 포트 번호, 프로토콜을 함께 사용해 통신 대상을 구분한다.


TCP 소켓과 UDP 소켓

앞에서 TCP는 연결형 통신이고, UDP는 비연결형 통신이라고 정리했다.

소켓에서도 사용하는 프로토콜에 따라 통신 흐름이 달라진다.

TCP를 사용하는 소켓은 먼저 연결을 맺은 뒤 데이터를 주고받고,
UDP를 사용하는 소켓은 연결 과정 없이 데이터를 보낼 때마다 목적지 주소를 지정한다.

특히 TCP 소켓은 연결형 통신이기 때문에 서버와 클라이언트의 초기 흐름이 서로 다르다.
서버는 클라이언트의 연결 요청을 기다려야 하고, 클라이언트는 서버에 연결을 요청해야 한다.

이제 TCP 서버와 TCP 클라이언트, 그리고 UDP 소켓의 통신 흐름을 각각 정리해보려고 한다.


TCP 서버의 통신 흐름

TCP 서버는 먼저 소켓을 만들고 특정 IP와 포트에 바인딩한 다음
클라이언트의 연결 요청을 기다린다.

TCP 서버의 기본적인 통신 흐름은 다음과 같다.

1. socket
2. bind
3. listen
4. accept
5. send / recv
6. close

각 단계의 의미는 다음과 같다.

단계 의미
socket 소켓 생성
bind 소켓에 IP 주소와 포트 번호를 부여
listen 클라이언트의 연결 요청 대기
accept 연결된 클라이언트와 통신할 전용 소켓 생성
send / recv 데이터 송수신
close 통신 종료

여기서 중요한 점은 accept이다.

서버가 처음 만든 소켓은 연결 요청을 기다리는 역할을 하고,
실제 클라이언트와 데이터를 주고받을 때는
accept를 통해 얻은 전용 소켓을 사용한다.


TCP 클라이언트의 통신 흐름

TCP 클라이언트는 서버에 연결을 요청하고 연결이 성립되면 데이터를 주고받는다.
TCP 클라이언트의 기본적인 통신 흐름은 다음과 같다.

1. socket
2. connect
3. send / recv
4. close

각 단계의 의미는 다음과 같다.

단계 의미
socket 소켓 생성
connect 서버에 연결 요청
send / recv 데이터 송수신
close 통신 종료

TCP는 연결형 통신이기 때문에
클라이언트는 데이터를 주고받기 전에 먼저 서버에 연결을 요청해야 한다.


UDP 통신 흐름

UDP 소켓은 비연결형 통신에 사용되고, sendto, recvfrom을 사용해 데이터를 주고받는다.
TCP처럼 연결을 만들고 유지하는 과정이 없으며, 데이터를 보낼 때마다 목적지 주소를 지정해서 전송한다.

UDP의 기본적인 통신 흐름은 다음과 같다.

1. socket
2. bind
3. sendto / recvfrom
4. close

각 단계의 의미는 다음과 같다.

단계 의미
socket 소켓 생성
bind 소켓에 IP 주소와 포트 번호를 부여
sendto / recvfrom 목적지 주소를 지정해 데이터 송수신
close 통신 종료

UDP 서버는 특정 포트에서 데이터를 받아야 하므로 보통 bind가 필요하다.

반면 UDP 클라이언트는 데이터를 보내기만 하는 경우라면
명시적으로 bind하지 않아도 운영체제가 임시 포트를 할당해줄 수 있다.

정리하면 TCP 소켓은 연결을 유지하면서 데이터를 주고받고,
UDP 소켓은 연결 없이 필요한 순간마다 목적지를 지정해 데이터를 보낸다.


게임에서 TCP와 UDP 사용 예시

게임에서도 TCP와 UDP를 모두 사용할 수 있다.

다만 같은 게임 플레이 로직 안에서 TCP와 UDP를 무작정 섞어 사용하면
메시지 도착 순서나 처리 타이밍이 달라져 논리 문제가 생길 수 있다.

예를 들어 아이템 장착은 TCP로 보내고, 공격 입력은 UDP로 보낸다고 해보자.
클라이언트가 다음 순서로 보냈다고 해도,

1. 아이템 장착 TCP
2. 공격 UDP

서버에서는 다음 순서로 받을 수도 있다.

1. 공격 UDP
2. 아이템 장착 TCP

이렇게 되면 아직 아이템을 장착하지 않은 상태에서 공격이 먼저 처리되는 문제가 발생할 수 있다.
따라서 같은 게임 플레이 로직 안에서는 하나의 통신 방식을 기준으로 잡고 처리하는 것이 더 안전하다.

대신 서버의 역할이나 데이터의 성격에 따라 TCP와 UDP를 구분해서 사용할 수 있다.

예를 들어 로그인, 인증, 결제, 계정 처리처럼 신뢰성이 중요한 서버에서는 TCP를 사용할 수 있다.
반면 실시간 위치 동기화나 입력 처리처럼
지연 시간이 중요한 게임 플레이 서버에서는 UDP 기반 통신을 사용할 수 있다.

정리하면 TCP와 UDP를 함께 사용할 수는 있지만,
하나의 로직 흐름 안에서 무작정 섞기보다는 서버 역할이나 데이터 성격에 따라 통신 방식을 구분하는 것이 좋다.


정리

TCP와 UDP는 전송 계층에서 사용되는 대표적인 프로토콜이다.

TCP는 연결형 통신이며, 3-way handshake를 통해 연결을 만든 뒤 데이터를 주고받는다.
또한 데이터의 순서와 재전송을 처리해주기 때문에 신뢰성이 중요한 통신에 적합하다.

반면 UDP는 비연결형 통신이며, 연결 확인 과정 없이 데이터를 메시지 단위로 보낸다.
데이터 전달이나 순서를 보장하지 않지만 상대적으로 지연이 낮아 실시간성이 중요한 통신에 적합하다.

Socket은 응용 프로그램이 운영체제의 네트워크 기능을 사용해 데이터를 주고받을 수 있게 해주는 통신의 끝점이다.

TCP 소켓은 connect, listen, accept를 통해 연결을 만들고 send, recv로 데이터를 주고받는다.
UDP 소켓은 연결 과정 없이 sendto, recvfrom으로 목적지를 지정해 데이터를 주고받는다.

게임에서는 신뢰성이 중요한 로그인, 결제, 계정 처리에는 TCP를 사용할 수 있고,
실시간 위치 동기화나 입력 처리에는 UDP를 사용할 수 있다.

다만 같은 게임 플레이 로직 안에서 TCP와 UDP를 무작정 섞어 사용하면
메시지 도착 순서나 처리 타이밍이 달라질 수 있으므로 주의해야 한다.


마무리

최근 언리얼 엔진의 RPC, Replicate 같은 네트워크 기능을 공부하면서
엔진이 많은 기능을 제공해주더라도 기본적인 네트워크 개념은 알아야겠다고 느꼈다.

예를 들어 어떤 데이터는 반드시 전달되어야 하고,
어떤 데이터는 조금 손실되더라도 최신 값이 더 중요한 경우가 있다.

이런 차이를 이해하려면 TCP와 UDP의 특징을 알고 있는 것이 도움이 된다.

다만 언리얼 엔진의 내부 네트워크 구현 방식까지는 아직 정확히 확인하지 않았기 때문에,
이번 글에서는 언리얼 내부 구현보다는 TCP와 UDP의 기본 차이와 소켓 통신 흐름을 정리하는 데 집중했다.

앞으로 언리얼 네트워크 기능을 더 공부하면서
Reliable, Unreliable, Replication 같은 개념도 따로 정리해봐야겠다.