TCP的流模式与UDP的报文模式对比
1?????? 案例背景
在學習TCP-IP協議詳解卷一時,讀到介紹TCP協議的部分,發現TCP的首部是沒有報文總長度字段的,而在UDP中是有的,對這個問題的思考引出了兩者之間的區別。
2??? 案例分析
TCP報文的格式:
?
TCP首部的格式:
?
UDP報文的格式:
?
UDP首部的格式:
?
針對首部公共部分的對比,很明顯的一個區別是UDP首部是有數據報總長度字段的,而TCP首部是沒有數據報總長度字段的,這個原因的解釋在TCP-IP詳解卷一答案中的解釋是TCP首部有選項字段而UDP首部大小是固定的,而網上的查詢結果有一種是因為模式的不同。
我比較贊同的是,TCP是面向連接的流模式,而UDP是不連接的數據報模式。
3?????? 實驗
實驗一:
?????? TCP客戶端循環發送數據到服務器,主循環部分分三次調用send或者sendto,分別發送111,222,333;而服務器是睡眠十秒,然后調用recv或者recvfrom接收數據。注意,只接收一次。
客戶端發送部分(其中的sendto可用send代替):
??? while(1)
?????? {
????????????? memset(achBuf,0,1024);
????????????? memcpy(achBuf,"111",3);
??????? buflen = strlen(achBuf);
????????????? ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));
????????????? memset(achBuf,0,1024);
????????????? memcpy(achBuf,"222",3);
??????? buflen = strlen(achBuf);
?????? ??? ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));
????????????? memset(achBuf,0,1024);
????????????? memcpy(achBuf,"333",3);
??????? buflen = strlen(achBuf);
?????? ??? ret = sendto(nSockFd,achBuf,buflen,0,(struct sockaddr*)&ServAddr,sizeof(ServAddr));
}
服務器接收部分(其中的recv可用recvfrom代替):
?????? sleep(10);
?????? recv(conn,buf,1024,0);
?????? printf("conn = %s\n",buf);
四種不同的發送接收組合,均是以下結果:
?
實驗二:
UDP客戶端循環發送數據到服務器,分三次調用sendto,分別發送了111,222,333;服務器睡眠十秒,然后調用recvfrom循環接收數據。為了表示是第幾次接收到的數據,首先打印接收序號。
客戶端發送部分:
?????? nNum = sendto(nSockFd,"111\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));
??? printf("nNum = %d\n",nNum);
?????? nNum = sendto(nSockFd,"222\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));
??? printf("nNum = %d\n",nNum);???
?????? nNum = sendto(nSockFd,"333\n", 12, 0, (struct sockaddr *)&MCAddr,sizeof(MCAddr));
??? printf("nNum = %d\n",nNum);
服務器接收部分:
?????? while(1)
?????? {
????????????? sleep(10);
????????????? memset(achBuf,0,MAXBUFLEN);
????????????? nNum = recvfrom(nServFd,achBuf,MAXBUFLEN,0,(struct sockaddr *)&CliAddr, &dwCliAddrLen);
?????????????
????????????? if(nNum < 0)
????????????? {
???????????????????? printf("recverror\n");
???????????????????? break;????
????????????? }
????????????? printf("%d\n",i);i++;
????????????? printf("%s\n",achBuf);
?????? }
結果如下圖:
?
4?????? 總結
由實驗結果可以知道,讀取數據的方式和調用的函數沒有關系,而和套接字類型有關。而TCP接收數據時不是一次只讀取一個數據報,而是根據buf的大小和緩沖區數據的大小中的較小值來讀取數據的,可以一次性讀取多個數據報;而UDP是按照接收到的數據次序,一次只讀取一個數據報。
現在可以大概的推敲出流模式和數據報模式的區別,接收和發送數據方式的不同。流模式只要不超過流的容量就可以繼續往流上提交數據,另一端只要流上有數據就可以讀取,而不管這個數據的開頭和結尾;數據報模式,有嚴格的次序關系和數據報的分割關系。而這兩種的不同大概是由于TCP一個套接字只接收來自一個對象的數據,而UDP套接字可以接收來自任意對象的數據。
兩者在模式上的不同,導致兩者在效率和應用模式上的不同。
在每個數據都要分析的情況下,例如發送一條配置命令,TCP必須約定消息頭格式指出這條消息的大小,而UDP不需要。而在流媒體數據上,由于TCP有數據重組的特性,效率相對UDP更高。
轉載于:https://www.cnblogs.com/leo0000/p/4863139.html
總結
以上是生活随笔為你收集整理的TCP的流模式与UDP的报文模式对比的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 有关Botton的用法(二)
 - 下一篇: 梦到鳄鱼和蛇打架是什么寓意