最近發現自己對於tcp通訊中的黏包問題還有疑問,查閱資料做下總結。
一、tcp黏包問題
tcp黏包問題是因為傳送方把若干資料傳送,接收方收到資料時候黏在一包,從接受緩衝區來看,後一包的資料黏在前一包的尾部。
二、黏包出現的原因
tcp黏包問題主要出現在兩個方面
(1)傳送方問題
首先tcp會預設使用nagle演算法,nagle演算法主要做兩件事。
第一:上一包分組得到確認,才會傳送下一分組。
第二:收集多個小組,在乙個確認到來時一起傳送。
由此可見nagle演算法會使得資料在傳送方造成黏包問題 。
(2)接收方問題
tcp接收方接收到分組的時候,並不會立刻提交到應用層處理,收到的資料放在接收快取裡面,然後應用程式會主動從接受快取裡讀取接收的分組,這樣以來,如果tcp接收分組的速度大於應用讀取分組的速度,多個包的資料會存至快取區裡面,應用讀取資料就可能會產生黏包問題。
三、什麼時候處理黏包問題
(1)如果每次利用tcp傳送資料,就與對方建立連線,然後傳送完資料就關閉連線這樣就不會出現黏包問題(大家都知道只傳送乙個資料報)
(2)如果傳送的資料無結構,比如檔案的傳輸,只要傳送方一直傳送,接收方只管接收到儲存的資料,此時也不用考慮黏包問題。
(3)如果在連線的一段時間內傳送的資料毫無關係,我們就要考慮黏包問題了。
比如:你要傳送一段話
i love you.
i want play.
如果產生了黏包問題,接收方可能會傻眼,你讓我幹啥?所以一般會在資料前加乙個長度之類的包,確保接收。
四、處理黏包現象
(1)傳送方
傳送方產生黏包問題的主要原因在於nagle演算法,我們可以通過關閉nagle演算法來解決,使用tcp_nodelay選項來關閉nagle演算法。
(2)接收方
由於tcp沒有處理接收方黏包現象的機制,我們只能在應用層進行處理。
(3)應用層處理
解決方法就是迴圈處理:應用程式在處理從快取讀來的分組時,讀完一條資料時,就應該迴圈讀下一條資料,直到所有的資料都被處理;但是如何判斷每條資料的長度呢?
兩種途徑:
1)格式化資料:每條資料有固定的格式(開始符、結束符),這種方法簡單易行,但選擇開始符和結束符的時候一定要注意每條資料的內部一定不能出現開始符或結束符。
2)傳送長度:傳送每條資料的時候,將資料的長度一併傳送,比如可以選擇每條資料的前4位是資料的長度,應用層處理時可以根據長度來判斷每條資料的開始和結束。
tcp和udp和黏包
tcp建立連線的過程 server端 import socket sk socket.socket 建立乙個socket物件 sk.bind 127.0.0.1 8088 繫結ip位址和埠 sk.listen while1 conn,addr sk.accept 等待建立連線 阻塞 直到連線建立才往...
TCP中分包,黏包解決辦法
粘包產生原因 先說tcp 由於tcp協議本身的機制 面向連線的可靠地協議 三次握手機制 客戶端與伺服器會維持一 個連線 channel 資料在連線不斷開的情況下,可以持續不斷地將多個資料報發往伺服器,但是如 果傳送的網路資料報太小,那麼他本身會啟用nagle演算法 可配置是否啟用 對較小的資料報進行...
python3 tcp黏包情況一
客戶端沒有及時接收緩衝區的包,造成多個包接收 服務端傳送了一段資料,客戶端只收了一小部分,客戶端下次再收的時候還是從緩衝區拿上次遺留的資料,產生粘包 tcp stickybag server.py coding utf 8 import socket import subprocess tcp se...