카테고리 보관물: Server

Server

TCP 및 UDP 패킷을 여러 조각으로 나눌 수 있습니까? 100 % 확신 할 수 있습니까? UDP

TCP 패킷이 조각으로 수신자에게 도착할 수 있습니까?

예를 들어, TCP 프로토콜을 사용하여 20 바이트를 보내는 경우 10 바이트가 아니라 10 바이트 정도가 아니라 한 번에 정확히 20 바이트를 수신한다고 100 % 확신 할 수 있습니까?

UDP 프로토콜에 대해서도 같은 질문입니다.
UDP를 신뢰할 수 없으며 패킷이 전혀 도착하지 않거나 다른 순서로 도착할 수는 없지만 단일 패킷은 어떻습니까? 도착하면 조각이 아닌 완전한 패킷인지 확인할 수 있습니까?



답변

TCP 패킷이 조각으로 수신기에 도착할 수 있습니까?

예. TCP는 일반적으로 경로 MTU를 결정하고 성능상의 이유로 패킷을보다 작게 유지하려고하지만 IP는 조각화를 지원합니다. 조각화는 데이터 그램 손실률을 치명적으로 증가시킵니다. 경로의 패킷 손실률이 10 % 인 경우 데이터 그램을 두 개의 패킷으로 조각화하면 데이터 그램 손실률이 거의 20 %가됩니다. 패킷 중 하나라도 손실되면 데이터 그램이 손실됩니다.

그래도 걱정할 필요가 없으며 TCP 레이어도 걱정하지 않아도됩니다. IP 계층은 패킷을 전체 데이터 그램으로 재 조립합니다.

예 : TCP 프로토콜을 사용하여 20 바이트를 보내면 10 바이트가 아니라 다른 10 바이트 정도 한 번에 정확히 20 바이트를 수신 할 것이라고 100 % 확신 할 수 있습니까?

아니요, 그러나 그것은 패킷과 관련이 없습니다. TCP는 기본적으로 응용 프로그램 메시지 경계를 유지하지 않는 바이트 스트림 프로토콜입니다.

UDP 프로토콜에 대해서도 같은 질문입니다. UDP를 신뢰할 수없고 패킷이 전혀 도착하지 않거나 다른 순서로 도착할 수 없다는 것을 알고 있습니다.

TCP에서도 마찬가지입니다. 패킷은 패킷입니다. 차이점은 TCP에는 재시도 및 재주문이 프로토콜에 내장되어 있지만 UDP는 그렇지 않다는 것입니다.

그러나 1 패킷은 어떻습니까? 도착하면 조각이 아닌 완전한 패킷인지 확인할 수 있습니까?

아니요, 그러나 그것은 당신의 문제가 아닙니다. UDP 프로토콜은 데이터 그램 리 어셈블리를 처리합니다. 그것은 그 일의 일부입니다. (실제로 IP 프로토콜은 UDP 프로토콜에 대해이 작업을 수행하므로 UDP는 단순히 IP 위에 계층화하여 수행합니다.) 데이터 그램이 두 개의 패킷으로 분할되는 경우 IP 프로토콜은 UDP 프로토콜에 대해이를 재구성합니다. 완전한 데이터를 볼 수 있습니다.


답변

그들이 실제로 물리적으로 한 번에 도착하는지 확신 할 수 없습니다. TCP / UDP 아래의 데이터 링크 계층은 원하는 경우 패킷을 분할 할 수 있습니다. 특히 인터넷이나 제어 할 수없는 네트워크를 통해 데이터를 보내면이를 예측하기가 어렵습니다.

그러나 데이터가 수신기에서 하나의 패킷 또는 여러 패킷에 도착하더라도 상관 없습니다. OS는 이러한 패킷의 연결을 추상화해야하므로 응용 프로그램의 경우 모든 것이 한 번에 도착한 것처럼 보입니다. 따라서 커널 해커가 아닌 한 대부분의 경우이 데이터가 하나 이상의 패킷으로 전송되는지 걱정할 필요가 없습니다.

UDP의 경우 OS는 추상화를 수행하므로 데이터를 수신하는 응용 프로그램은 데이터가 전송 된 패킷 수를 알 필요가 없습니다. 그러나 TCP와의 차이점은 데이터가 실제로 도착한다는 보장이 없다는 것입니다. 데이터가 여러 패킷으로 분할 될 수 있으며 일부는 도착하지만 일부는 도착하지 않을 수 있습니다. 수신 응용 프로그램의 경우 완료 여부에 관계없이 데이터 스트림처럼 보입니다.


답변

예. 연속 문자 블록은 send () 호출에 해당합니다.

TCP :

Send: AA BBBB CCC DDDDDD E         Recv: A ABB B BCC CDDD DDDE

전송 된 모든 데이터는 순서대로 수신되지만 반드시 동일한 청크 일 필요는 없습니다.

UDP :

Send: AA BBBB CCC DDDDDD E         Recv: CCC AA E

데이터의 순서가 반드시 같을 필요는 없으며 전혀 수신 할 필요는 없지만 메시지는 전체적으로 보존됩니다.


답변

예 : TCP 프로토콜을 사용하여 20 바이트를 보내면 10 바이트가 아니라 다른 10 바이트 정도 한 번에 정확히 20 바이트를 수신 할 것이라고 100 % 확신 할 수 있습니까?

TCP는 스트림 프로토콜이며 데이터를 순서대로 유지하지만 메시지별로 그룹화하지는 않습니다. 반면에 UDP는 메시지 지향적이지만 신뢰할 수 없습니다. SCTP 는 두 가지 장점을 모두 갖추고 있지만 NAT가 인터넷을 차단하기 때문에 기본적으로 사용할 수 없습니다.


답변

TCP 스트림의 맨 처음에 20 바이트를 보내면 두 개의 10 바이트 조각으로 도착하지 않을 것이라는 확신이 있습니다. 이는 TCP 스택이 이러한 작은 세그먼트를 보내지 않기 때문입니다. 최소 MTU 크기가 있습니다. 그러나, 센드가 스트림 중앙 어딘가에 있으면 모든 베팅이 해제됩니다. 프로토콜 스택은 세그먼트를 채우고 전송하기 위해 10 바이트의 데이터를 소비 한 다음 다음 10 바이트는 다른 세그먼트로 이동합니다.

프로토콜 스택은 데이터를 청크로 나누고 대기열에 넣습니다. 청크 크기는 경로 MTU를 기반으로합니다. 전송 작업을 수행하는데 여전히 대기중인 데이터가있는 경우 프로토콜 스택은 일반적으로 대기열의 끝에있는 세그먼트를 들여다보고 해당 세그먼트에 더 많은 데이터를 추가 할 공간이 있는지 확인합니다. 공간은 1 바이트만큼 작을 수 있으므로 2 바이트 전송도 2 개로 나눌 수 있습니다.

다른 한편으로, 데이터의 분할은 부분 판독이있을 수 있음을 의미합니다. 수신 작업은 하나의 세그먼트에 도착할 때 잠재적으로 깨어나 데이터를 얻을 수 있습니다. 광범위하게 구현 된 소켓 API에서 수신 호출은 20 바이트를 요청할 수 있지만 10으로 리턴 할 수 있습니다. 물론 20 바이트를 수신하거나 연결이 끊길 때까지 차단하는 버퍼링 계층을 작성할 수 있습니다. POSIX 세계에서이 API는 표준 I / O 스트림 일 수 있습니다 fdopen. 소켓 디스크립터가 FILE *스트림 을 확보 할 수 fread있으며이를 사용 하여 전체 요청이 read필요한만큼의 호출로 만족되도록 버퍼를 채울 수 있습니다 . .

UDP 데이터 그램은 데이터의 프레임을 구성합니다. 각 송신 호출은 데이터 그램을 생성합니다 (하지만 코킹에 대해서는 아래 참조). 다른 쪽은 전체 데이터 그램을받습니다 (그리고 소켓 API에서이를 보유 할만큼 큰 버퍼를 지정해야합니다. 그렇지 않으면 데이터 그램이 잘립니다). 큰 데이터 그램은 IP 조각화로 조각화되고 응용 프로그램에 투명하게 다시 어셈블됩니다. 조각이 없으면 전체 데이터 그램이 손실됩니다. 해당 상황에서 부분 데이터를 읽을 수있는 방법이 없습니다.

여러 작업에서 단일 데이터 그램을 지정할 수있는 인터페이스 확장이 있습니다. Linux에서 소켓은 “코르크”될 수 있습니다 (전송 금지). 데이터가 코르크 처리되는 동안 기록 된 데이터는 단일 장치로 조립됩니다. 그런 다음 소켓이 “확인되지 않은”경우 단일 데이터 그램을 보낼 수 있습니다.


답변