2012-04-25 3 views
0

TCP 소켓에서 send()에 관한 질문이 있습니다.socket send() repeatable

차이가된다

char *text="Hello world"; 
char buffer[150]; 

for(i=0;i<10;i++) 
    send(fd_client, text, strlen(text)); 

char *text="Hello world"; 
char buffer[150]; 

buffer[0]='\0'; 
for(i=0;i<10;i++) 
    strcat(buffer, text); 

send(fd_client, buffer, strlen(buffer)); 

는 RECV을 이용하여 수신 측에 대한 차이가 있습니까? 둘 다 하나의 TCP 패킷이됩니까?

TCP_NODELAY가 설정 되더라도?

답변

0

정말 알 수있는 방법이 없습니다. TCP 구현에 따라 다릅니다. 그것이 UDP 소켓이라면 첫 번째 경우에는 여러 개의 패킷을, 두 번째 경우에는 여러 개의 패킷을 가질 수있는 결과가 분명히 다를 것입니다.

TCP는 적합하다고 판단되는 패킷을 자유롭게 분할 할 수 있습니다. 스트림을 에뮬레이션하고 사용자로부터 패킷 메커니즘을 추상화합니다. 이는 의도적으로 설계된 동작입니다.

0

TCP는 스트림 기반 프로토콜입니다. 보내기를 실행하면 OS의 TCP 레이어 버퍼에 데이터가 저장되고 OS는 주기적으로 데이터를 전송합니다. 그러나 Send를 너무 빨리 호출하면 이전 배열이 전송되기 전에 몇 개의 배열을 OS TCP 계층에 넣을 수 있습니다. 그래서 그것은 스택과 같습니다, 그것은 무엇이든 보내고 모든 것을 하나의 큰 배열에 넣습니다.
송신은 OS TCP 계층에 의한 세그먼테이션으로 수행되며 OSL 버퍼가 하나의 세그먼트 크기를 만족시키기에 충분하기 전에 소량의 데이터를 전송하지 못하게하는 Nagle의 알고리즘이 있습니다.

그래, 차이가 있습니다.

TCP는 스트림 기반 프로토콜이기 때문에 동일한 데이터 양으로 단일 수신을받을 수는 없습니다.
데이터가 병합 될 수 있으며 항상 기억해야합니다.

Btw, 예제를 기반으로, 첫 번째 경우 클라이언트는 모든 바이트를 함께 받거나 아무것도 수신하지 않습니다. 그 사이에 하나의 커다란 세그먼트를 보내면 도중에 서버 OS가 자동으로 다시 보내 게됩니다. 더 큰 패킷에 대한 드롭 기회가 더 높아지고 큰 세그먼트의 재전송은 트래픽 손실을 초래할 것입니다. 그러나 이것은 패킷 손실의 비율을 기반으로하며 실제로 귀하의 경우에는 그렇지 않을 수도 있습니다.

두 번째 예에서는 모든 것을 함께 받거나 각각의 부분 또는 일부를 병합 할 수 있습니다. 당신은 알지 못하고 네트워크 읽기를 구현해야합니다. 즉, 얼마나 많은 바이트를 받고 그만큼의 바이트를 읽어야하는지 알 수 있습니다. 그렇게하면 읽지 않은 바이트가 남아 있어도 다음 "읽기"에서 읽혀집니다.