티스토리 뷰

IT/Network

[네트워크] TCP/UDP의 데이터의 경계가 있다 없다는 의미는 무엇일까?

주인장 진빼이

데이터의 경계가 없다는 것이 무슨 뜻일까?

책을 통해 얻은 정보를 정리해본다.

 

" 사탕 100개가 여러 번에 걸쳐서 옆사람에게 보내졌다. 그러나 받는 사람은 사탕 100개가 쌓인 다음에 이를 한 번에 봉지에 담아 갔다. "

이는 데이터의 경계가 없다(TCP)고 볼 수 있다.

 

" 택배를 통해 수령할 물건이 2개인데 동시에 받을 수 없으므로 각 1번씩 3번 수령해야 한다. "

이는 데이터의 경계가 있다(UDP)고 볼 수 있다.

 

 

TCP 프로토콜에서 통신이 진행될 때, 클라이언트에서 서버에게 10의 크기를 가진 데이터 송신을 10번 진행한다고 가정하자. 총 크기는 100바이트다. 이는 매우 적은 크기라고 볼 수 있다. (한번 송신할 때 보낼 수 있는 최대 크기는 MTU와 연관이 있음) 클라이언트는 send 함수를 10번 호출하여 데이터를 10번 송신한다.

 

반면에 서버는 단 한 번만 recv 함수를 호출하여 모든 데이터를 수신할 수 있다.

이처럼 송신 함수의 호출 횟수와 수신 함수의 호출 횟수가 일치하지 않아도 된다라는 의미는 데이터의 경계가 없다고 볼 수 있다.

 

 

 

 

 

반대로 UDP 프로토콜에선 데이터의 경계가 존재한다.

즉, 송신 함수의 호출 횟수와 수신 함수의 호출 횟수가 반드시 일치해야 한다는 것이다.

 

코드와 예제를 통해 알아보겠다.

먼저 클라이언트가 서버에게 짧은 시간에 3회 데이터를 송신했다.

char msg1[] = "HELLO UDP SERVER!";
char msg2[] = "Message sent!";
char msg3[] = "See you again";

sendto(hClntSock, msg1, sizeof(msg1), 0, (LPSOCKADDR)&toAddr, sizeof(SOCKADDR_IN));
sendto(hClntSock, msg2, sizeof(msg2), 0, (LPSOCKADDR)&toAddr, sizeof(SOCKADDR_IN));
sendto(hClntSock, msg3, sizeof(msg3), 0, (LPSOCKADDR)&toAddr, sizeof(SOCKADDR_IN));

 

 

 

서버는 5초(5000ms) 주기로 recvfrom 함수를 호출하여 데이터를 수신하는데

중요한 건 수신하는 버퍼 크기는 30이란 것이다.

 

하지만 버퍼 크기와 상관없이 클라이언트는 3회 데이터를 송신했기 때문에 서버 또한 3회 데이터를 수신해야 한다.

이처럼 송신 함수의 호출 횟수와 수신 함수의 호출 횟수를 일치해야 하는 것을 데이터의 경계가 있다고 볼 수 있다.

#define BUF_SIZE 30
for (int i = 0; ; ++i)
{
    Sleep(5000);
    fromAddrSize = sizeof(fromAddr);
    recvfrom(hServSock, message, BUF_SIZE, 0, (LPSOCKADDR)&fromAddr, &fromAddrSize);
    if (strlen(message))
    {
      	cout << i << ">> " <<  message << "\n";
    }
}

 

결과

UDP: 서버는 5초 주기로 클라이언트가 보낸 데이터를 한번씩 수신하고 있는 모습을 볼 수 있다.

이미 데이터가 모두 송신되었음에도 불구하고 데이터의 경계가 있으므로 한번에 모든 데이터를 수신할 수 없다.

즉, 5초 주기로 1회, 2회, 3회 각각 송신한 데이터에 대해서 수신하고 있다.

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함