# 면접 단골 질문 : TCP와 UDP를 비교해봐라 !
TCP와 UDP의 차이점은 개발자라면 알아야 하는 상식이며 면접에서도 자주 나온다. 때문에 나도 이 질문을 들으면 자동적으로 "둘은 트랜스포트 계층에서 사용하는 프로토콜로, TCP는 연결 지향형이고 신뢰성있는 연결을 보장하고 혼잡 제어를 하고 어쩌구저쩌구..." 대답을 하는 편이긴 한데, 기계적으로 답하는 것보단 각각이 정확히 무엇인지 신입 수준에서 조금 더 자세히 살펴보고자 한다.
1. Transport Layer : Application과 Internet 계층 사이
TCP/IP 4계층에서 트랜스포트 계층은 어플리케이션 계층과 인터넷 계층의 사이에 위치한다. 응용 프로그램에서 네트워크에 이용할 데이터를 받아서, IP 주소를 통해 목적지로 향하는 인터넷 계층으로 내려주는 역할을 한다. 논리적 통신과 물리적 통신의 중간 단계에 위치한다고 생각해도 좋을 것 같다.
트랜스포트 계층에서 중요한 것은 포트 번호이다. 포트 번호는 컴퓨터에서 실행중인 프로세스를 구분하기 위해 16비트로 구분해놓은 할당 번호인데, HTTP 통신에는 80번, HTTPS 통신에는 443번이 이용된다. 인터넷 계층을 통해 받고자 하는 패킷이 컴퓨터로 도착한 뒤, 컴퓨터에서 사용하는 프로그램들 중 어떤 프로그램에 해당 패킷이 도착해야하는지 결정해야한다. 여기서 트랜스포트 계층에서 사용하는 PDU인 세그먼트의 헤더가 등장한다. TCP, UDP와 상관 없이 트랜스포트 계층의 세그먼트엔 목적지 주소의 포트번호가 존재한다.
트랜스포트 계층에선 신뢰성 있는 연결을 하도록 한다. 여기서 말하는 신뢰성 있는 연결이란, 주고받는 데이터에 오류나 손실이 없다는 뜻이다. 이를 위해 인터넷 계층에서 보낸 패킷의 유실이나 오류를 검출하고 수복하는 과정이 필요하다. 트랜스포트 계층에서 사용하는 프로토콜은 대표적으로 TCP와 UDP가 있는데, 일반적으로 사용하는 TCP 프토로콜은 이를 달성하기 위해 IP와 협동하여 전송한 각각의 패킷에 대해 오류 검사와 수신 확인을 한다.
자세한 것은 다음 TCP 설명을 확인하자.
2. TCP : 연결형 프로토콜
TCP는 연결형 프로토콜로, 서버와 클라이언트가 연결되어야만 통신이 가능하다. 트랜스포트 계층에서 지향하는 신뢰성 있는 연결을 보장한다.
TCP는 가상 회선 방식을 사용한다. 인터넷을 통한 네트워크는 지역간의 LAN, 그리고 전 세계를 잇는 WAN을 통해 유무선을 넘나들며 패킷 단위로 이뤄진다. 지금 이순간에도 해저 케이블이나 무선 통신이 이뤄지는 공간에선 수백, 수천 억개의 패킷들이 교환되고 있을 것이다. 이런 어지러운 네트워크 세계에서 TCP 프로토콜을 통한 패킷들은 한 번 연결이 성사되면 각각의 송수신 장소를 알고 그 사이에서만 양방향 통신을 하게 된다. 이러한 전이중(Full-duplex), 점대점(Point to Point) 특징을 가진 TCP 통신이 마치 전화 통화 같다고해서 가상 회선이라고 불린다.
또한 TCP는 수신자가 데이터를 받는 속도가 느리거나 네트워크가 혼잡했을 때 전송 속도를 조절하는 흐름제어 및 혼잡제어 기능도 갖추고 있다.
송신측이 보낸 세그먼트는 인터넷 계층에서 분할되어 위와 같이 순서대로 가상회선을 타고 수신측에 도착한다.
2-1. TCP 헤더 구성
어플리케이션 계층의 데이터를 받은 트랜스포트 계층에서는 데이터에 헤더를 추가한 뒤 인터넷 계층에 내려보낸다. TCP 계층에서 사용하는 헤더의 구성은 아래 그림과 같다.
- Source/Destination Port : 출발지와 목적지 컴퓨터의 포트 번호로, 트랜스포트 계층에서 가장 중요한 정보이다.
- Sequence Number : 출발지 기준 패킷의 시퀀스 번호. 바이트 수 기준으로 증가한다. 보내는 쪽에서 이 값이 N이라면 받는 쪽에서 Acknowledgement Number을 N+{받은 데이터 byte}로 설정해서 다시 보낸다. 이를 통해 보내는 쪽은 N번 패킷이 상대방에게 잘 도착했다는 수신확인을 할 수 있다.
- Acknowledgement Number : 특정 Sequence Number를 가진 패킷을 잘 받았다는 수신확인을 위해 사용하는 필드이다. 역시 바이트 기준으로 증가한다. 프로세스가 특정 Acknowledgement Number를 가진 패킷을 받으면 해당 프로세스는 이 Sequence Number를 가진 패킷을 보내게 된다.
- Window Size : TCP 흐름 제어에 필요한 항목. 수신 측에서 수신 데이터 버퍼의 남은 값을 설정해서 수신확인 패킷을 반환하면 송신측은 이에 맞춰 다음 데이터를 보낸다.
- SYN : 연결 시작을 위해 사용되는 flag bit. 양 쪽이 보낸 최초의 패킷에만 이 값이 1로 설정된다.
- ACK : 패킷을 받는 쪽에서 패킷이 잘 도착했음을 알리는 수신 확인에 사용하는 flag bit.
- FIN : 연결 종료를 위해 사용하는 flag bit.
2-2. 3-way handshaking
가상 회선을 구축하고 TCP 통신을 시작하기 위해 TCP는 3-way handshaking을 한다.
A 프로세스 -> B 프로세스 방향으로 데이터를 보내기 위해 통신을 시작하는 과정을 살펴보자. TCP 세그먼트가 인터넷 계층에서 여러 패킷으로 분할되어 다음과 같이 전송된다. 다음 정보들은 모두 TCP 헤더에 위치한다.
- A에서 특정 Sequence Number를 가진 패킷을 SYN 비트를 1로 설정하여 B로 전송한다. 해당 패킷을 보낸 A는 이후 SYN_SENT 상태가 된다.
- 연결 시작 패킷(SYN=1)을 받은 B는 SYN_RCV 상태가 된다. 해당 패킷을 받았다는 수신 확인을 위해, 그리고 본인 역시 통신을 시작할 준비가 됐음을 알리기 위해 패킷의 SYN과 ACK 비트를 1로 설정한다. 그리고 (A가 설정한 Sequence Number + 1) 값을 Acknowledgement Number로 설정하여 다음 패킷을 보내라는 수신확인을 한다.
- B에게 SYN 플래그를 되받은 A는 ESTABLISHED 상태가 되어 본격적으로 통신을 한다. 데이터를 보내기 전, B가 보낸 SYN 패킷을 수신했다는 신호로 (B가 설정한 Sequence Number + 1) 값을 Acknowledgement Number로 설정한다. 그리고 B가 보낸 Acknowledgement Number에 맞춰 Sequence Number을 설정한 후 해당 번호에 맞는 패킷을 전송한다.
이 이후 A와 B는 본격적으로 양방향 데이터를 송수신할 수 있게 된다.
2-3. TCP 통신 과정
TCP 통신은 전반적으로 패킷 송신 -> 수신 확인 -> 다음 패킷 송신 의 과정을 통해 이뤄진다. 전송한 데이터의 손실이 없음을 보장하기 위해 TCP는 상대방이 데이터를 잘 받았음을 수신 확인하는 과정이 필요하다는 것이 특징이다.
다음 예시는 통신 과정중 별다른 문제가 없을 때 TCP 통신 과정이다. A가 200바이트의 데이터를 두 번 보내고, B가 받는 상황이다.
- A -> B : A는 seq번호가 1200인 100바이트 패킷을 보낸다.
- B -> A : B는 seq번호가 1200인 100바이트 패킷을 잘 받았다. A에게 다음으로 보낼 패킷의 seq번호를 ack번호로 설정하여 패킷을 반환한다.
- A -> B : B가 seq번호 1200번, 100바이트의 패킷을 잘 받았음을 확인한다. seq번호가 1301인 100바이트 패킷을 보낸다.
- B -> A : B는 seq번호가 1301인 100바이트 패킷을 잘 받았다. A에게 다음으로 보낼 패킷의 seq번호를 ack번호로 설정하여 패킷을 반환한다.
- 반복.
앞서 sequence number와 acknowledge number는 바이트 단위로 증가한다는 설명을 상기하자.
Ack 번호 = Seq번호 + 전송된 데이터 byte 크기 + 1
임을 알 수 있다.
만약, A가 특정 시퀀스 번호를 가진 데이터 패킷을 보냈는데 B에서 해당 패킷에 맞는 수신확인 패킷이 도착하지 않는 상황에선 어떨까?
전반적인 과정은 앞과 같지만, Time Out이 발생한 뒤 재전송이 일어남을 확인할 수 있다. 이렇게 TCP에선 수신확인이 이뤄지지 않았을 때, 즉 패킷 손실이 발생했을 때 데이터를 재전송함으로써 패킷 손실에 대비한다.
2-4. 4-way handshaking
양방향 통신이 끝나고, TCP 연결이 해제되는 과정은 4-way handshaking을 통해 이뤄진다. TCP 연결 해제에서 중요한 점은 연결이 해제되기 전 미처 도착하지 못한 패킷에 대비하는 것이다. 전송되어야 할 패킷이 남은 상황에서 한 쪽에서 일방적으로 연결을 끊어버리면, 상대방은 자신이 보낸 패킷이 잘 수신되었는지 확인할 수 없다. 이 경우를 대비하기 위해 TCP는 wait 상태를 둔 4-way handshaking을 실행한다.
프로세스 A가 B와 TCP 연결 회선을 끊고자 하는 상황을 가정하고 과정을 살펴보자.
- A는 FIN flag를 1로 설정하여 세그먼트를 보낸다. 이후 A는 FIN_WAIT 상태에 들어간다.
- FIN 플래그를 받은 B는 ACK 플래그가 1인 세그먼트를 보낸다. B는 CLOSE_WAIT 상태에 들어간다.
- 만약 B가 아직 보내지 못한 패킷이 있으면 계속 보낸다. FIN_WAIT 상태에 있는 A는 B가 보내는 데이터를 받을 수만 있다.
- 위 그림에서 B가 FIN 플래그를 받은 뒤 5바이트의 데이터를 추가로 보내고, A가 수신확인 세그먼트를 반환하는 과정을 확인하자
(근데 그림이 잘못된 것 같은데.. 이때 Ack=67이 되어야 할 것 같다)
- B가 FIN flag를 1로 설정하여 세그먼트를 보낸다.
- 이를 받은 A는 마지막으로 ACK flag를 1로 설정한 세그먼트를 보낸다. 그리고 TIME_WAIT 상태로 2MSL(Maximum Segment Lifetime, 세그먼트가 네트워크 선상에 존재할 수 있는 최대 시간) 동안 기다린다.
- 이는 연결이 종료된 후, 혹시 모를 회선 상에 존재하는 지연 패킷을 위함이다.
2-2 ~ 2-4에서 설명한 통신 과정을 보면, 결국 TCP는 보내고자 하는 데이터의 무결성을 유지하기 위해 전송한 모든 패킷에 대해 수신확인을 하는 과정을 거침을 알 수 있다. 이를 통해 TCP에선 다소 느리더라도 안정적이고 신뢰성 있는 데이터 교환이 가능하다.
3. UDP : 비연결형 프로토콜
UDP는 트랜스포트 계층의 비연결형 프로토콜로, 사전에 서버와 클라이언트의 연결이 필요 없다. UDP는 데이터그램이라는 전송 단위로 네트워크 통신을 한다.
UDP는 트랜스포트 계층의 일반적인 특징을 따르지 않는다. 신뢰성 있는 통신이 이뤄지지 않는다는 의미이다. 통신 시작 전 가상 회선을 구축하고, 전송한 각각의 데이터 세그먼트에 대해 수신확인을 하는 TCP와는 다르게 UDP는 사전 연결 설정 없이 송신 측에서 일방적으로 데이터그램을 보내기만 한다. 데이터를 잘 받았는지 확인하는 과정이 없으므로, 데이터그램의 유실이 발생했을 때 재전송하지 않는다. 손실된 데이터는 손실된 데이터 자체로 끝이다.
또한 UDP는 TCP에서 갖춘 흐름제어, 혼잡제어의 기능을 갖추고 있지 않다. 앞서 언급했지만 통신 역시 양방향이 아니라 송신 쪽에서 일방적으로 데이터를 보내기만 하는 단방향 통신이다.
또한 상호간 가상회선을 구축하고 종단간 1:1 통신만을 하는 TCP와 다르게, UDP는 데이터그램을 보낼 수 있는 곳이라면 어디든 보낼 수 있다. 하나의 송신 프로세스가 여러 개의 수신 프로세스로 데이터그램을 뿌리는 방식으로 1:N 통신이 가능하다.
2-1. UDP 헤더 구성
UDP의 헤더 구성을 보자. TCP보다 훨씬 간단한 형식이다.
- Source/Destination Port Number : 송신측과 수신측의 포트 번호이다. UDP 역시 트랜스포트 계층의 프로토콜이므로 헤더에 포트 번호가 존재해야 한다.
- Total Length : 헤더와 데이터 부분을 전부 포함한 데이터그램의 크기를 정의한다.
- Checksum : 데이터그램의 오류를 검출하기 위해 사용한다. 만약 이를 통해 오류가 감지되면 수신측은 해당 데이터그램을 버린다.
2-2. UDP 통신 과정
통신 과정이라고 할 것도 없다. 보내는 쪽에서 데이터그램에 알맞게 헤더를 채워넣은 뒤 일방적으로 데이터를 보내기만 한다.
과정을 보고 예상이 들었겠지만, UDP는 헤더가 복잡하지 않고 재전송 과정이 없는만큼 TCP보다 가볍고 빠르다는 특징이 있다.
UDP는 TCP처럼 사전에 구축한 가상회선 없이 각각의 데이터그램을 단발로 보낼 뿐이다. 패킷의 전송 경로가 다르고 따로 흐름제어의 과정이 없으므로 도착 순서 역시 보장하지 않는다.
4. 두 프로토콜의 비교
앞서 정리한 내용을 바탕으로 두 프로토콜의 공통점과 차이점으로 중요하게 꼽아볼만한 내용을 표로 정리해보았다.
TCP | UDP | |
전송 속도 | slow | fast |
데이터 신뢰성 | good | bad |
패킷 교환 방식 | 가상 회선 | 데이터그램 |
흐름/혼잡 제어 여부 | O | X |
특징 | 연결형 프로토콜 | 비연결형 프로토콜 |
공통점 | 트랜스포트 계층의 프로토콜로, 헤더에 포트 번호가 포함됨 |
TCP는 느리다. 하지만 교환되는 데이터에 오류가 없다.
UDP는 빠르다. 하지만 통신 데이터에 오류가 있을 가능성이 높다. 네트워크가 혼잡할 경우 유실률이 20% 가까이 되는 경우도 있다고 한다.
때문에 UDP는 데이터에 다소 오류가 있더라도 실시간으로 빠른 데이터의 교환이 필요한 라이브 스트리밍 서비스나 영상물 통신에 많이 쓰이고, TCP는 그 외 정확한 데이터 교환이 필요한 일반적인 네트워크 상황에서 많이 쓰인다.
REFERENCE
https://gmlwjd9405.github.io/2018/09/19/tcp-connection.html
https://mangkyu.tistory.com/15