Socket/TCP粘包、斷包

TCP(transport control protocol,傳輸控制協(xié)議)是面向連接的,面向流的,提供高可靠性服務(wù)。收發(fā)兩端(客戶端和服務(wù)器端)都要有一一成對的socket,因此,發(fā)送端為了將多個發(fā)往接收端的包,更有效的發(fā)到對方,使用了優(yōu)化方法(Nagle算法),將多次間隔較小且數(shù)據(jù)量小的數(shù)據(jù),合并成一個大的數(shù)據(jù)塊,然后進行封包。這樣,接收端,就難于分辨出來了,必須提供科學(xué)的拆包機制。即面向流的通信是無消息保護邊界的。

UDP(user datagram protocol,用戶數(shù)據(jù)報協(xié)議)是無連接的,面向消息的,提供高效率服務(wù)。不會使用塊的合并優(yōu)化算法, 由于UDP支持的是一對多的模式,所以接收端的skbuff(套接字緩沖區(qū))采用了鏈?zhǔn)浇Y(jié)構(gòu)來記錄每一個到達的UDP包,在每個UDP包中就有了消息頭(消息來源地址,端口等信息),這樣,對于接收端來說,就容易進行區(qū)分處理了。即面向消息的通信是有消息保護邊界的。

由于TCP無消息保護邊界, 需要在消息接收端處理消息邊界問題。

粘包的原因

發(fā)送端需要等緩沖區(qū)滿才發(fā)送出去,造成粘包

接收方不及時接收緩沖區(qū)的包,造成多個包接收

斷包的原因

以太網(wǎng)中存在一個對于幀的有效數(shù)據(jù)大小的限制,即MTU,以太網(wǎng)的MTU為1500字節(jié)。所謂斷包就是說發(fā)送端一次發(fā)送的消息長度過大,如果超過了MTU,那么ip會對其進行分片,導(dǎo)致接收端接收到消息后,無法確定是否是一個完整的消息。

粘包/斷包的解決思路

粘包/斷包問題的最本質(zhì)原因在與接收對等方無法分辨消息與消息之間的邊界在哪。

通過使用某種方案給出邊界,例如:

發(fā)送定長包。如果每個消息的大小都是一樣的,那么在接收對等方只要累計接收數(shù)據(jù),直到數(shù)據(jù)等于一個定長的數(shù)值就將它作為一個消息;

包尾加上\r\n標(biāo)記。FTP協(xié)議正是這么做的。但問題在于如果數(shù)據(jù)正文中也含有\(zhòng)r\n,則會誤判為消息的邊界;

包頭加上包體長度。包頭是定長的4個字節(jié),說明了包體的長度。接收對等方先接收包體長度,依據(jù)包體長度來接收包體;

使用更加復(fù)雜的應(yīng)用層協(xié)議。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容