关于TCP的粘包问题
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                关于TCP的粘包问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                
                            
                            
                            簡單的說就是通過TCP協議發送了多條獨立的數據,但接收的時候,有些數據不幸的合并成了一個。比如客戶端向服務器發送兩個命令:”Start”、”Parameter[x.x.x]”,第一個命令的含義是開始,第二個命令的含義是啟動參數。但是服務器接收的時候,很可能不是分兩次接收,而是一次接收到”StartParameter[x.x.x]”,這下全亂了。
 
UDP丟包是因為數據包在傳送過程中丟失了 而TCP是基于流式的發送 并且存在丟包重發機制 TCP是可靠連接而UDP是不可靠的這個我就不多說了 
關于TCP的粘包 正是由于TCP是流式傳送的 也就是連接建立后可以一直不停的發送 并沒有明確的邊界定義 而你用UDP發送的時候 是可以按照一個一個數據包去發送的 一個數據包就是一個明確的邊界 
而TCP并沒有數據包的概念 是完全流式的 他會開辟一個緩沖區 發送端往其中寫入數據 每過一段時間就發送出去 然后接收端接收到這些數據 但是并不是說我發送了一次數據就肯定發送出去了 數據會在緩沖區中 有可能后續發送的數據和之前發送的數據同時存在緩沖區中隨后一起發送 這就是粘包的一種形式 接收端也有產生粘包的情況 如果應用程序沒有及時處理緩沖區中的數據 那么后續到達的數據會繼續存放到緩沖區中 也就是2次接收的數據同時存在緩沖區中 下次取緩沖區的時候就會取出2次粘包后的數據 這是粘包的另外一種形式 還有其他許多形式 比如填充緩沖區到一半緩沖區滿了直接發送了 但是其實那個包還沒填充完全 這個就是不完整的粘包了 剩余數據會在下次發送的時候補上關于解決方法 如果你是連續的整個數據流 比如發送文件 那么完全不考慮粘包也無所謂 因為可以建立連接后發送 發送完畢后斷開連接 整個數據流就是整個一個文件 無論數據從那里切開都無所謂 整個拼接后依舊是整個一個文件的數據
如果你發送的數據是多次通信 比如把一個目錄下所有的文件名都發送過去 那么就不能當作一個整體發送了 必須對他們劃分邊界 有一個很簡單的處理方法 就是采用"數據長度+實際數據"的格式來發送數據 這個"數據長度"的格式是固定寬度的 比如4字節 可以表示0~4GB的寬度了 足夠用了 這個寬度說明了后續實際數據的寬度 這樣你就可以把粘包后的數據按照正確的寬度取出來了 
每次都是取出4字節 隨后按照正確的寬度取出后續部分的就OK了
如果你的所有數據都是固定寬度的 比如不停的發送溫度數據 每個都是1字節 那么寬度已知了 每次你都取出一個1字節就OK了 所以就不用發送寬度數據了 
當然你也可以按照建立連接斷開連接來劃分邊界 每次發送數據都打開關閉一次連接 不過對于頻繁的小數據量是不可取的做法 因為開銷太大 建立連接和關閉連接也是需要耗費網絡流量的
總而言之 粘包的情況是無法絕對避免的 因為網絡環境是很復雜的 依賴發送和接收緩沖區的控制是不能保證100%的 只要在發送的數據中說明數據的寬度隨后在接收部分按照這個寬度拆開就OK了 寬度全都是統一的已知寬度的情況下拆開更加容易 連在發送端填入寬度數據都可以省去了
                            
                        
                        
                        總結
以上是生活随笔為你收集整理的关于TCP的粘包问题的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 浏览器多代理配置 - SwitchyOm
- 下一篇: c++使用Lua
