[네트워크] TCP와 UDP

2022. 5. 22. 13:29TIL💡/Network

앞에서 설명한 2,3계층은 목적지를 정확히 찾아가기 위한 주소 제공이 목적이었지만 4계층에서 동작하는 프로토콜은 목적이 2,3계층 프로토콜과 조금 다르다. 목적지 단말 안에서 동작하는 여러 애플리케이션 프로세스 중 통신해야 할 목적지 프로세스를 정확히 찾아가고 패킷 순서가 바뀌지 않도록 잘 조합원래 데이터를 잘 만들어내기 위한 역할을 한다.

 

4계층 프로토콜(TCP, UDP)과 서비스 포트

데이터를 보내고 받는 인캡슐레이션, 디캡슐레이션 과정에 각 계층에서 정의하는 헤더가 추가되고 여러 가지 정보가 들어간다.

다양한 정보 중 가장 중요한 두 가지 정보는 아래와 같다.

 

✔︎ 각 계층에서 정의하는 정보

✔︎ 상위 프로토콜 지시자 정보

 

 

각 계층을 정의하는 정보는 수신 특의 동일 계층에서 사용하기 위한 정보이다. 예를 들어 송신 측에서 추가한 2계층 헤더의 MAC 주소 정보는 수신 측의 2계층에서 확인하고 사용된다. 마찬가지로 송신 측에서 추가한 3계층 IP 주소는 수신 측 3계층에서 사용한다. 4계층에서는 이런 정보로 시퀀스 번호, ACK 번호가 있다.

 

상위 프로토콜 지시자디캡슐레이션 과정에서 상위 계층의 프로토콜이나 프로세스를 정확히 찾아가기 위한 목적으로 사용된다. 2계층은 이더 타입, 3계층은 프로토콜 번호, 4계층은 포트 번호가 상위 프로토콜 지시자이다. 

TCP/IP 프로토콜 스택에서 4계층은 TCP와 UDP가 담당한다. 4계층(트랜스포트)의 목적은 목적지를 찾아가는 주소가 아니라 애플리케이션에서 사용하는 프로세스를 정확히 찾아가고 데이터를 분할한 패킷을 잘 쪼개 보내고 잘 조립하는 것이다.

 

패킷을 분할하고 조합하기 위해 TCP 프로토콜에서는 시퀀스 번호와 ACK 번호를 사용한다.

 

 

두 헤더의 공통된 내용인 SP는 Source Port, DP는 Destination Port를 의미한다.

 

TCP/IP 프로토콜 스택에서 4계층의 상위 프로토콜 지시자는 포트 번호이다. 일반적으로 TCP/IP에서는 클라이언트-서버 방식으로 서비스를 제공하고 클라이언트용 프로그램과 서버용 프로그램을 구분해 개발한다. 3계층의 프로토콜 번호나 2계층의 이더 타입과 같은 상위 프로토콜 지시자는 출발지와 도착지를 구분해 사용하지 않고 한 개만 사용하지만 4계층 프로토콜 지시자인 포트 번호는 출발지와 도착지를 구분해야 한다.

 

TCP 🔥

TCP 프로토콜은 신뢰할 수 없는 공용망에서도 정보 유실 없는 통신을 보장하기 위해 세션을 안전하게 연결하고 데이터를 분할하고 분할된 패킷이 잘 전송되었는지 확인하는 기능이 있다. 패킷에 번호(Sequence Number)를 부여하고 잘 전송되었는지에 대해 응답(Acknowledge Number)한다. 또한, 한꺼번에 얼마나 보내야 수신자가 잘 받아 처리할 수 있는지 전송 크기(Window Size)까지 고려해 통신한다. TCP의 여러 역할 덕분에 네트워크 상태를 심각하게 고려하지 않고 특별한 개발 없이도 쉽고 안전하게 네트워크를 사용할 수 있다.

 

패킷 순서, 응답번호

패킷에 순서를 부여하는 것을 시퀀스 번호, 응답 번호를 부여하는 것을 ACK 번호라고 부른다. 두 번호가 상호작용해 순서가 바뀌거나 중간에 패킷이 손실된 것을 파악할 수 있다.

보내는 쪽에서 패킷에 번호를 부여하고 받는 쪽은 이 번호의 순서가 맞는지 확인한다.

받은 패킷 번호가 맞으면 응답을 주는데 이때 다음 번호의 패킷을 요청한다. 이 숫자를 ACK 번호라고 부른다.

 

예를 들어 송신 측이 1번 패킷을 보냈는데 수신 측이 이 패킷을 잘 받는다면 1번을 잘 받았으니 다음에는 2번을 달라는 표시로 ACK 번호 2를 줍니다.

 

윈도 사이즈와 슬라이딩 윈도우

TCP는 일방적으로 패킷을 보내는 것이 아니라 상대방이 얼마나 잘 받았는지 확인하기 위해 ACK 번호를 확인하고 다음 패킷을 전송한다. 패킷이 잘 전송되었는지 확인하기 위해 별도 패킷을 받는 것 자체가 통신 시간을 늘리지만 송신자와 수신자가 먼 거리에 떨어져 있으면 왕복 지연시간(Round Trip Time, RTT)이 늘어나므로 응답을 기다리는 시간이 더 길어진다. 작은 패킷을 하나 보내고 응답을 받아야만 하나를 더 보낼 수 있다면 모든 데이터를 전송하는 데 긴 시간이 걸릴 것이다.

 

그래서 데이터를 보낼 때 패킷을 하나만 보내는 것이 아니라 많은 패킷을 한꺼번에 보내고 응답을 하나만 받는다.

가능하면 최대한 많은 패킷을 한꺼번에 보내는 것이 효율적이지만 네트워크 상태가 안 좋으면 패킷 유실 가능성이 커지므로 적절한 송신량을 결정해야 하는데 한 번에 데이터를 받을 수 있는 데이터 크기를 윈도 사이즈라고 하고 네트워크 상황에 따라 이 윈도 사이즈를 조절하는 것을 슬라이딩 윈도라고 한다. 

 

TCP는 데이터에 유실이 발생하면 윈도 사이즈를 절반으로 떨어뜨리고, 정상적인 통신이 되는 경우 서서히 하나씩 늘린다. 네트워크에 경합이 발생해 패킷 드롭이 생기면 작아진 윈도 사이즈로 인해 데이터 통신 속도가 느려져 회선을 제대로 사용하지 못하는 상황이 발생한다. 이런 경우 경합을 피하기 위해 회선 속도를 증가시키거나 경합을 임시로 피하게 할 수 있는, 버퍼가 큰 네트워크 장비를 사용하거나 TCP 최적화 솔루션을 사용해 이런 문제를 해결할 수 있다.

 

3방향 핸드셰이크

목적지가 데이터를 받을 준비가 안 된 상황에서 데이터를 일방적으로 전송하면 목적지에서는 데이터를 정상적으로 처리할 수 없어 데이터가 버려진다. TCP 프로토콜은 이런 상황을 만들지 않기 위해 통신 전, 데이터를 안전하게 보내고 받을 수 있는지 미리 확인하는 작업을 거친다.

 

3방향 핸드셰이크 과정이 생기다보니 기존 통신과 새로운 통신을 구분해야 한다.

어떤 패킷이 새로운 연결 시도이고 기존 통신에 대한 응답인지 구분하기 위해 헤더에 플래그(Flag)라는 값을 넣어 통신한다.

 

TCP 헤더(http://www.ktword.co.kr/test/view/view.php?m_temp1=1889)

TCP 플래그는 총 6가지가 있고 통신의 성질을 나타낸다. 초기 연결, 응답, 정상 종료, 비정상 종료 등의 용도로 사용된다.

 

✔︎ SYN

연결 시작 용도로 사용한다. 연결이 시작될 때 SYN 플래그에 1로 표시해 보낸다.

 

✔︎ ACK

ACK 번호가 유효할 경우, 1로 표시해 보낸다.

초기 SYN이 아닌 모든 패킷은 기존 메시지에 대한 응답이므로 ACK 플래그가 1로 표기된다.

 

✔︎ FIN

연결 종료 시 1로 표시된다. 데이터 전송을 마친 후 정상적으로 양방향 종료 시 사용된다.

 

✔︎ RST

연결 종료 시 1로 표시된다. 연결 강제 종료를 위해 연결을 일방적으로 끊을 때 사용된다.

 

✔︎ URG

긴급 데이터인 경우, 1로 표시해 보낸다.

 

✔︎ PSH

서버 측에서 전송할 데이터가 없거나 데이터를 버퍼링 없이 응용 프로그램으로 즉시 전달할 것을 지시할 때 사용된다.

 

 

UDP 🔥

TCP와 달리 UDP는 4계층 프로토콜이 가져야 할 특징이 거의 없다.

4계층에서는 신뢰성 있는 통신을 위해 연결을 미리 확립(3방향 핸드셰이크)했고 데이터를 잘 분할하고 조립하기 위해 패킷 번호를 부여하고 수신된 데이터에 대해 응답하는 작업을 수행했다. 데이터를 특정 단위(윈도 사이즈)로 보내고 메모리에 유지하다가 ACK 번호를 받은 후 통신이 잘 된 상황을 파악하고 나서야 메모리에서 이 데이터들을 제거했다. 중간에 유실이 있으면 시퀀스 번호와 ACK 번호를 비교해가며 이를 파악하고 메모리에 유지해놓은 데이터를 이용해 재전송하는 기능이 있다. 이 기능을 이용해 데이터 유실이 발생하거나 순서가 바뀌더라도 바로잡을 수 있다. 이런 특징들은 TCP만 해당된다. UDP에는 이런 기능이 전혀 없다.

 

UDP는 데이터 전송을 보장하지 않는 프로토콜이므로 제한된 용도로만 사용된다.

 

UDP는 음성 데이터나 실시간 스트리밍과 같이 시간에 민감한 프로토콜이나 애플리케이션을 사용하는 경우나 사내 방송이나 증권 시세 데이터 전송에 사용되는 멀티캐스트처럼 단방향으로 다수의 단말과 통신해 응답을 받기 어려운 환경에서 주로 사용된다. 이것은 대부분 음성이나 동영상과 같이 사람이 청각, 시각적으로 응답 시간에 민감한 경우이다. 음성, 동영상은 디지털 환경에서는 연속된 데이터가 아닌 매우 짧은 시간 단위로 잘게 분할한 데이터가 전송되는 형태이다.동영상은 1초 동안 30~60회의 정지 영상이 빠르게 바뀌면서 우리 눈에는 마치 움직이는 영상처럼 보이는 원리를 이용한다.

 

반대로 실 세계 데이터를 디지털화할 때는 시간을 잘게 쪼개 데이터를 샘플링하는데 이런 데이터들은 다른 일반 데이터처럼 취근하면 시간 지연에 따른 어려움이 있다. 중간에 데이터가 몇 개쯤 유실되는 것보다 재전송하기 위해 잠시 동영상이나 음성이 멈추는 것을 더 이상하게 느낄 수 있다. 이렇게 데이터를 전송하는 데 신뢰성보다 일부 데이터가 유실되더라도 시간에 맞추어 계속 전송하는 것이 중요한 화상회의 시스템인 경우 UDP를 사용하게 된다.

 

UDP는 TCP와 달리 통신 시작 전, 3방향 핸드셰이크와 같이 사전에 연결을 확립하는 절차가 없다. 그 대신 UDP에서 첫 데이터는 리소스 확보를 위해 인터럽트(interrupt)를 거는 용도로 사용되고 유실된다. 그래서 UDP 프로토콜을 사용하는 애플리케이션이 대부분 이런 상황을 인지하고 동작하거나 연결 확립은 TCP 프로토콜을 사용하고 애플리케이션끼리 모든 준비를 마친 후 실제 데이터만 UDP를 이용하는 경우가 대부분이다.

 

같은 동영상 스트리밍이더라도 넷플릭스나 유튜브와 같이 시간에 민감하지 않은 단일 시청자를 위한 연결은 TCP를 사용한다.
이 경우, 원활한 시청을 위해 수 초 ~ 수 분의 동영상 데이터를 미리 받아놓고 네트워크에 잠시 문제가 발생하더라도 동영상이 끊기지 않도록 캐시에 저장한다.

하지만 실시간 화상회의 솔루션(ex. zoom)의 경우, 데이터 전송이 양방향으로 일어나고 시간에 매우 민감하게 반응하므로 TCP 이용 환경에서 데이터 유실이 발생하면 사용자는 네트워크 품질이 나쁘다고 생각할 수 있다. 이때 UDP를 사용해야 한다.

TCP와 UDP의 특징 비교

💡 참고

✔︎ 전이중(Full Duplex)

- 두 디바이스간 통신선이 2개

- 송신선과 수신선이 각각 존재하므로 동시 송수신 가능

 

✔︎ 반이중(Half Duplex)

- 두 디바이스간 통신선이 1개

- 한쪽 디바이스에서 송신과 수신 모두 가능

- 하나의 통신선으로 송신과 수신을 해야 하므로 송신과 수신을 동시에 할 수 없다. 한 쪽이 송신시 다른 쪽에서는 수신만 가능

- 송신과 수신을 번갈아가며 통신할 때 데이터 전송 간격이 짧고 속도가 빠르면 마치 Full Duplex 같이 느껴짐