TCP/UDP 데이터 전송
호스트에서 다른 호스트로 세 개의 연속된 메시지를 TCP/UDP를 통해 전송하면 어떻게 될까?
UDP
UDP는 message-oriented protocol이라고 한다.

각 메시지는 별도의 Datagram에 담아서 인터넷을 통해 목적지로 전달한다.
인터넷을 통해 전달하는 과정에서 IP(인터넷 프로토콜)을 사용하는데, unreliable(비신뢰성) 특성을 가지고 있다.
이 특성의 의미는 아래와 같으며 UDP 또한 unreliable 하다.
패킷(IP)의 전달이 보장되지 않는다. 전송 과정에서 손상되거나 소실될 수 있다.
전송 패킷의 순서가 바뀔 수 있으며, 중복 전송 가능성도 있다.
목적지에 도착했는지 확인/보장하지 않는다.
message-oriented protocol은 다음과 같은 특징이 있다.
보낸 메시지 단위 그대로 받을 수 있게 해주는 프로토콜이다.
메시지 간의 경계를 구분할 수 있다. (byte-stream protocol과 대조되는 주요 특징)
한 번에 전송 가능한 메시지의 최대 크기가 존재한다. (프로토콜 특성상 메시지를 개별 단위로 처리하기 때문에 발생하는 제한사항)
소켓에서의 동작
전달하는 호스트에서는 sendto() 시스템 콜을 호출해서 데이터를 전송한다. (비연결 지향적이기 때문에 매번 목적지의 주소 정보를 함께 전달)
목적지 호스트에서는 recvfrom() 시스템 콜을 호출해서 송신지 정보와 함께 데이터를 수신한다.
TCP
TCP는 byte-stream protocol 혹은 byte-oriented protocol, stream-oriented protocol 이라고도 한다.

UDP와 달리 메시지의 경계를 구분하지 않고 보내려고 하는 데이터를 byte의 흐름(stream)으로 전송한다.
UDP에서는 메시지를 Datagram에 담아서 전송했는데, TCP는 어떻게 전송할까?
바로 TCP이다. TCP의 특징은 아래와 같다.
TCP는 데이터를 연속적인 바이트의 흐름으로 취급하여 메시지 경계를 구분하지 않고 데이터를 전송한다.
데이터를 Segment 단위로 분할하여 전송한다.
TCP Segment란, 애플리케이션에서 보낸 메시지와는 독립적으로 특정 크기로 구분되는 별도의 전송 단위이다.데이터의 순서를 보장하고, 손실된 패킷을 재전송하며 중복 패킷을 제거한다. 이를 통해
신뢰할 수 있는(reilable)데이터 전송을 실현하는 것을 목적으로 한다.TCP 세그먼트에는
MSS(Maximum Segment Size)라는제약 사항(특정 크기)가 있다.
🤔 원래 3개의 메시지를 하나의 바이트 스트림으로 전송하면 수신하는 측에서는 어떻게 데이터를 구분하지?
이 책임(메시지 단위로 다시 구분하는 행위)은 TCP에 있지 않기 때문에 해당 프로토콜을 사용하는 쪽에서 해야 한다.
소켓에서의 동작
3개의 메시지를 보내기 위해서는 전달하는 호스트에서 3번의 send() 시스템 콜을 호출한다.
이 메시지들은 개별로 전송되는 것이 아니라, 하나의 byte-stream으로 합쳐져서 전송된다.
목적지 호스트에서는 3번의 read() 시스템 콜을 호출하는 것이 아니라, 단 한 번의 호출로 전부 읽을 수 있다.
read() 시스템 콜로 수신한 데이터(byte-stream)을 원래의 메시지 단위로 데이터를 구분하는 것은 TCP 프로토콜의 책임이 아니며, 이를 사용하는 애플리케이션 계층에서 처리해야 한다.
Q&A
Q: byte-stream protocol은 reliable 한가?
A: reliable 여부는 독립적인 개념이다.
byte-stream protocol이 reilable 하다면, TCP이고 그렇지 않으면 그냥 unreliable byte-stream protocol이다.
message-oriented protocol이 reliable 하다면, 그냥 reliable message-oriented protocol이고, 아니면 UDP이다.
Q: UDP를 통해 max UDP datagram size 보다 큰 메시지를 전송하려고 하면?
A: 실패하고 에러를 받는다. 에러 처리는 개발자나 application layer protocol이 구현해야 한다.
Q: TCP를 통해 MSS 보다 큰 메시지를 전송하려고 한다면?
A: TCP가 알아서 MSS에 맞는 TCP segment들로 나눠서 전송한다.
Q: byte-stream protocol을 사용하는 호스트에서 메시지를 구분하는 방법은 어떤 것들이 있나?
A: 여러 가지 존재한다.
메시지 사이즈를 고정한다. (전송 데이터 하나가 20bytes라고 정의하면, 수신 측에서도 20bytes로 자르면 된다.)
메시지의 사이즈를 먼저 보낸 후 메시지를 보낸다. (수신 측에서 메시지 경계를 구분할 수 있다.)
메시지에 구분자를 사용한다. (예: CRLF) 수신 측에서 이를 기준으로 메시지를 구분할 수 있다.
Q: TCP가 byte-stream protocol 이라면 TCP 위에서 동작하는 HTTP는 자체적으로 HTTP message의 경계를 구분하는 방법을 가지고 있나?
A: 맞다. HTTP는 TCP의 byte-stream protocol 특성을 고려하여 자체적으로 HTTP 메시지의 경계를 구분하는 방법을 가지고 있다. (HTTP 버전에 따라 달라지는 부분이 존재한다.)
HTTP는 시작 라인, 헤더, 공백 라인, 바디로 구성되는데 공백 라인을 사용하여 헤더와 바디를 구분하거나, Content-Length header에 메시지 바디 길이를 명시하여 수신자가 정확히 어디까지가 현재 메시지인지 파악할 수 있다.

Reference: 쉬운코드
Last updated