본문 바로가기

네트워크

[네트워크] TCP, UDP는 무엇인가?

이 글은 TCP, UDP를 참고하여 작성된 글입니다.

📤 전송 계층

전송 계층은 앤드 포인트 간에 신뢰성 있는 데이터 전송을 담당하는 계층이다. 데이터를 순차적이고, 안정적인 전달을 가능케 하며, 해당되는 포트의 프로세스에 데이터를 전달하는 역할을 한다.

 

이러한 역할을 하는 전송계층이 없다면, 송신자가 보낸 데이터의 순서가 보장될 수 없다. 또한, 송신자의 데이터 전달 속도와 수신자의 데이터 수신 속도가 맞지 않는다면, 데이터가 누락될 수 있으며, 네트워크의 데이터 속도가 느리다면 이 또한 혼잡 문제를 일으킬 수 있다. 이를 흐름 문제, 혼잡 문제라 한다.

🧐 TCP (Transmission Control Protocol) 란 무엇일까?

앤드 포인트간에 신뢰성 있는 데이터를 전송할 수 있도록 하기 위한 프로토콜이다. 즉, 데이터의 순차적인 전송을 보장, 흐름을 제어하며 혼잡을 제어, 에러 또한 감지한다.

🤔 TCP의 특징을 살펴보자.

우선, TCP는 연결 지향으로, 통신을 하기 전에 2개의 호스트가 연결(Connection)되어 있어야 한다. TCP는 호스트 간의 연결을 설정하기 위해 3-way handshaking을 한다.

🤝 3-way handshaking

3-way handshaking을 이해하기 위해 다음과 같은 이해가 필요하다. 

 

TCP는 데이터를 Segment 단위로 관리한다. 응용 계층에서 전달된 데이터를 내부적으로 잘라 각각의 잘라진 데이터에 TCP 해더를 추가하여 만들어진 것이다. (TCP 해더에 대해서 더 알아보고 싶다면, 이 곳을 참고하자.)

 

TCP 해더 중 9bit의 플래그 필드가 존재하는데, 이 부분은 TCP 연결을 제어하고, 데이터를 관리하는 부분으로 비트 중 ACK, SYN, FIN 이라는 세 가지 플래그가 있다. 

 

SYN은 Connection을 할 때 연결을 담당하는 플래그 비트이다. FIN은 연결을 종료시키기 위해 사용하는 플래그 비트, ACK는 전달받은 송신자의 데이터를 전달받은 수신자가 수신 확인을 전달하는 플래그 비트이다. 

 

이미지 출처

 

LISTEN, 서버는 클라이언트의 요청을 대기하고 있는 상태이다. 

 

SYN_SENT, 클라이언트가 서버와 연결하기 위해 SYN 플래그 비트에 1을 담아 패킷을 전송한다. 

 

SYN_RECEIVED, 서버는 클라이언트의 수신을 확인했다는 의미로 ACK 플래그 비트에 클라이언트로부터 전달받은 SYN 플래그 비트 값인 1에 1을 더한 값을 담고, 또한, TCP는 양방향 통신이기 때문에 서버도 클라이언트에게 연결을 요청하기 위해 시퀀스 번호를 생성하여 SYN 플래그 비트에 담아 두 가지 패킷을 함께 전송한다.

 

클라이언트 ESTABLISHED, 서버에서 전송된 패킷 중 ACK 플래그 비트의 값이 클라이언트 자신이 보낸 SYN 플래그 비트의 값과 1 차이가 나는 것을 확인하면, 전송이 잘 되었다는 의미로 받아드리고 서버의 SYN 패킷에 들어있는 플래그 비트 값에 1을 더하여 ACK 플래그 비트에 값을 담아 서버에게 전송하고, 자신의 상태를 ESTABLISHED로 변경한다.

 

서버 ESTABLISHED, 클라이언트에서 전달받은 SYN 패킷의 값이 자신이 보낸 ACK 패킷의 값과 1의 차이라면 잘 수신되었다는 뜻으로 알고 서버의 상태를 ESTABLISHED로 변경한다.

 

이후 통신 과정을 통해 데이터를 주고 받는데, 클라이언트에서 패킷을 전송하면, 패킷 전송이 확인되었다는 의미로 서버는 ACK 패킷을 보내주어야 한다. 클라이언트의 패킷 전송이 올바르지 않았다면, 클라이언트는 서버로부터 ACK 패킷을 전송받지 못할 것이고, 클라이언트는 패킷을 재전송하여 서버의 ACK를 다시 한번 기다린다.

 

🤝 4-way handshaking

서버와 클라이언트간에 연결을 종료하기 위한 과정을 4-way handshake라 한다.

 

이미지 출처

 

클라이언트에서 더 이상 전송할 데이터가 없다면 FIN 플래그 비트의 값을 1로 설정한 패킷을 서버 측에 전달한다.

 

FIN 패킷을 전달받은 서버측은 수신 확인을 ACK 패킷을 통해 전송한다.

 

하지만, 바로 연결을 종료하는 것이 아니라, 서버 쪽에서 클라이언트로 전송할 데이터가 남아있을 수 있기 때문에 우선 클라이언트는 대기 상태로 기다린다.

 

서버에서 전송할 데이터가 모두 클라이언트으로 전송되었다면, 마찬가지로 FIN 패킷을 클라이언트에게 전송한다.

 

클라이언트는 FIN 패킷의 수신 확인을 위해 ACK를 보내고 서버는 상태를 CLOSED로 변경한다.

 

🤔 TCP의 단점은 무엇일까?

데이터를 신뢰성있게 전송하기 위해 사용되는 TCP는 위와 같이 데이터를 전송받기 전에 3-way handshake의 연결 과정을 거치기 때문에 시간이 지연될 수밖에 없다. 또는 클라이언트에서 전송한 데이터가 조금만 손실되었다면, 클라이언트는 재전송을 해야 한다. 

 

이러한 문제점을 해결하기 위해 등장한 또 다른 프로토콜이 바로 UDP 이다. 

🧐 UDP (User Datagram Protocol) 란 무엇일까?

UDP는 TCP보다 전송의 신뢰성은 떨어지지만, 전송속도가 비교적 빠른 프로토콜이다. TCP로 가능한 흐름 제어, 혼잡 제어, 데이터의 순차 전송은 불가능하지만, 비교적 데이터의 신뢰성이 중요하지 않을 때 유용하게 사용된다.

 

🤔 UDP의 특징을 살펴보자.

UDP는 비 연결지향이다. 즉, 연결과정 없이 데이터를 전송하기 때문에 연결 설정 및 해제 과정이 없이 에러 감지만 가능하다.

 

UDP는 응용 계층에서 전달받은 데이터에 UDP 해더를 추가하여 데이터를 관리하며 이를 User Datagram이라 한다. TCP에서는 데이터를 쪼개어 사용했다면, UDP에서는 데이터를 쪼개지 않고 그대로 사용하기 때문에 UDP를 사용하기 위해선 응용 계층에서 데이터를 쪼개 내려야 한다.

 

UDP 해더는 TCP 해더보다 간단하다. (UDP 해더에 대해서 더 알아보고 싶다면, 이 곳을 참고하자.)

 

데이터 전송과정 또한 간단하다. 서버는 UDP 관련 소켓을 열어두고, 데이터 송신을 원하는 측에서 데이터를 전송한다.