在socket網絡編程中,都是端到端通信,由客戶端端口+服務端端口+客戶端IP+服務端IP+傳輸協議組成的五元組可以明確的標識一條連接。在TCP的socket編程中,發送端和接收端都有成對的socket。發送端為了將多個發往接收端的包,更加高效的的發給接收端,於是采用了優化算法(Nagle算法),將多次間隔較小、數據量較小的數據,合並成一個數據量大的數據塊,然后進行封包。那么這樣一來,接收端就必須使用高效科學的拆包機制來分辨這些數據。
1.Q:什么是TCP粘包問題?
TCP粘包就是指發送方發送的若干包數據到達接收方時粘成了一包,從接收緩沖區來看,后一包數據的頭緊接着前一包數據的尾,出現粘包的原因是多方面的,可能是來自發送方,也可能是來自接收方。
2.Q:造成TCP粘包的原因
(1)發送方原因
TCP默認使用Nagle算法(主要作用:減少網絡中報文段的數量),而Nagle算法主要做兩件事:
只有上一個分組得到確認,才會發送下一個分組
收集多個小分組,在一個確認到來時一起發送
Nagle算法造成了發送方可能會出現粘包問題
(2)接收方原因
TCP接收到數據包時,並不會馬上交到應用層進行處理,或者說應用層並不會立即處理。實際上,TCP將接收到的數據包保存在接收緩存里,然后應用程序主動從緩存讀取收到的分組。這樣一來,如果TCP接收數據包到緩存的速度大於應用程序從緩存中讀取數據包的速度,多個包就會被緩存,應用程序就有可能讀取到多個首尾相接粘到一起的包。
3.Q:什么時候需要處理粘包現象?
如果發送方發送的多組數據本來就是同一塊數據的不同部分,比如說一個文件被分成多個部分發送,這時當然不需要處理粘包現象
如果多個分組毫不相干,甚至是並列關系,那么這個時候就一定要處理粘包現象了
4.Q:如何處理粘包現象?
(1)發送方
對於發送方造成的粘包問題,可以通過關閉Nagle算法來解決,使用TCP_NODELAY選項來關閉算法。
(2)接收方
接收方沒有辦法來處理粘包現象,只能將問題交給應用層來處理。
(2)應用層
應用層的解決辦法簡單可行,不僅能解決接收方的粘包問題,還可以解決發送方的粘包問題。
解決辦法:循環處理,應用程序從接收緩存中讀取分組時,讀完一條數據,就應該循環讀取下一條數據,直到所有數據都被處理完成,但是如何判斷每條數據的長度呢?
格式化數據:每條數據有固定的格式(開始符,結束符),這種方法簡單易行,但是選擇開始符和結束符時一定要確保每條數據的內部不包含開始符和結束符。
發送長度:發送每條數據時,將數據的長度一並發送,例如規定數據的前4位是數據的長度,應用層在處理時可以根據長度來判斷每個分組的開始和結束位置。
5.Q:UDP會不會產生粘包問題呢?
TCP為了保證可靠傳輸並減少額外的開銷(每次發包都要驗證),采用了基於流的傳輸,基於流的傳輸不認為消息是一條一條的,是無保護消息邊界的(保護消息邊界:指傳輸協議把數據當做一條獨立的消息在網上傳輸,接收端一次只能接受一條獨立的消息)。
UDP則是面向消息傳輸的,是有保護消息邊界的,接收方一次只接受一條獨立的信息,所以不存在粘包問題。
舉個例子:有三個數據包,大小分別為2k、4k、6k,如果采用UDP發送的話,不管接受方的接收緩存有多大,我們必須要進行至少三次以上的發送才能把數據包發送完,但是使用TCP協議發送的話,我們只需要接受方的接收緩存有12k的大小,就可以一次把這3個數據包全部發送完畢。
————————————————
版權聲明:本文為CSDN博主「漁溪大王」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_41047704/article/details/85340311