tcp是面向連線的,互動雙方的程序各自建立乙個流式套接字,伺服器需要等待客戶端向其提出連線申請。一旦接受客戶端申請就立刻返回乙個新的套接字描述符。通過該描述符呼叫資料傳輸函式與客戶端進行資料的收發。
udp是面向無連線的,雙方建立的是資料報套接字,伺服器和客戶端在進行傳描資料之前不需要進行連線的申請和建立,可以隨時向對方發訊息。
什麼時候需要考慮粘包問題
1:如果利用tcp每次傳送資料,就與對方建立連線,然後雙方傳送完一段資料後,就關閉連線,這樣就不會出現粘包問題(因為只有一種包結構,類似於http協議)。關閉連線主要要雙方都傳送close連線(參考tcp關閉協議)。如:a需要傳送一段字串給b,那麼a與b建立連線,然後傳送雙方都預設好的協議字元如"hello give me sth abour yourself",然後b收到報文後,就將緩衝區資料接收,然後關閉連線,這樣粘包問題不用考慮到,因為大家都知道是傳送一段字元;
2:如果傳送資料無結構,如檔案傳輸,這樣傳送方只管傳送,接收方只管接收儲存就ok,也不用考慮粘包;
3:如果雙方建立連線,需要在連線後一段時間內傳送不同結構資料,如連線後,有好幾種結構:
1)「hellogive me sth abour yourself」
2)「don』tgive me sth abour yourself」
那這樣的話,如果傳送方連續傳送這個兩個包出去,接收方一次接收可能會是"hello give me sth abour yourselfdon』t give me sth abouryourself" 這樣接收方就傻了,到底是要幹嘛?不知道,因為協議沒有規定這麼詭異的字串,所以要處理把它分包,怎麼分也需要雙方組織乙個比較好的包結構,所以一般可能會在頭加乙個資料長度之類的包,以確保接收。
粘包出現原因:
在流傳輸**現,udp不會出現粘包,因為它有訊息保護邊界。
1 傳送端需要等緩衝區滿才傳送出去,造成粘包
2 接收方不及時接收緩衝區的包,造成多個包接收
解決辦法:
為了避免粘包現象,可採取以下幾種措施:
一是對於傳送方引起的粘包現象,使用者可通過程式設計設定來避免,tcp提供了強制資料立即傳送的操作指令push,tcp軟體收到該操作指令後,就立即將本段資料傳送出去,而不必等待傳送緩衝區滿;
二是對於接收方引起的粘包,則可通過優化程式設計、精簡接收程序工作量、提高接收程序優先順序等措施,使其及時接收資料,從而盡量避免出現粘包現象;
三是由接收方控制,將一包資料按結構字段,人為控制分多次接收,然後合併,通過這種手段來避免粘包。
以上提到的三種措施,都有其不足之處。
第一種程式設計設定方法雖然可以避免傳送方引起的粘包,但它關閉了優化演算法,降低了網路傳送效率,影響應用程式的效能,一般不建議使用。
第二種方法只能減少出現粘包的可能性,但並不能完全避免粘包,當傳送頻率較高時,或由於網路突發可能使某個時間段資料報到達接收方較快,接收方還是有可能來不及接收,從而導致粘包。
第三種方法雖然避免了粘包,但應用程式的效率較低,對實時應用的場合不適合。
更為簡潔的說法:
定包長包尾加\r\n
包頭加包體長度
網上說法:
個人比較喜歡的一種做法是給一幀資料加幀頭幀尾,然後接收方不斷接受並快取收到的資料,根據幀頭幀尾分離出一幀完整的資料,再分離各欄位得到資料
C 網路程式設計
首先我們解釋一下在網路程式設計時候,經常遇到的幾個概念 同步 synchronous 非同步 asynchronous 阻塞 block 和非阻塞 unblock 所謂同步方式,就是傳送方傳送資料報以後,不等接受方響應,就接著傳送下乙個資料報。非同步方式就是當傳送方傳送乙個資料報以後,一直等到接受方...
C 網路程式設計
1 ip網路中的每台主機都有乙個ip位址 它是邏輯位址 網際網路上的ip位址具有全球唯一性 4個位元組,192.168.0.16 2 osi將網路分為 tcp ip模型 應用層 應用層 表示層會話層 傳輸層 傳輸層 網路層 網路層 資料鏈路層 網路介面 物理層相同層次之間不可以直接通訊,是虛擬通訊。...
c 網路程式設計
microsoft.framework為應用程式訪問inter 提供了分層的 可擴充套件的以及受管轄的網路服務,其名字空間system.和system.sockets包含豐富的類可以開發多種網路應用程式。類採用的分層結構允許應用程式在不同的控制級別上訪問網路,開發人員可以根據需要選擇針對不同的級別編...