如何理解字節(jié)流?
之所以會說TCP是面向字節(jié)流的協(xié)議,UDP是面向報文的協(xié)議,是因為操作系統(tǒng)對TCP和UDP協(xié)議的發(fā)送方的機制不同,也就是問題原因在發(fā)送方
為什么UDP協(xié)議是面向報文的協(xié)議?
?當(dāng)用戶消息通過UDP協(xié)議傳輸時,操作系統(tǒng)不會對消息進行拆分,在組裝好UDP頭部后就交給網(wǎng)絡(luò)層來處理,所以發(fā)出去的UDP報文中的數(shù)據(jù)部分就是完整的用戶消息,也就是每個UDP報文就是一個用戶消息的邊界,這樣接收方在接收到UDP報文后,讀取一個UDP報文就能讀取到完整的用戶消息。
操作系統(tǒng)在接收到UDP報文后,會將其插入到隊列里,隊列里的每一個元素都是一個UDP報文,這樣當(dāng)用戶調(diào)用recvfrom()系統(tǒng)調(diào)用讀數(shù)據(jù)的時候,就會從隊列中取出一個數(shù)據(jù),然后從內(nèi)核里拷貝給用戶緩沖區(qū)。
?為什么說TCP是面向字節(jié)流的協(xié)議?
當(dāng)用戶消息通過TCP協(xié)議傳輸時,消息可能會被操作系統(tǒng)分組成多個的TCP報文,也就是一個完整的用戶消息被拆分成多個TCP報文進行傳輸。
這時,接收方的程序如果不知道發(fā)送方發(fā)送的消息長度,也就是不知道消息的邊界時,是無法讀出一個有效的用戶消息的,因為用戶消息被拆分成多個TCP報文后,并不能像UDP那樣,一個UDP報文就能代表一個完整的用戶消息。
eg:
發(fā)送方準(zhǔn)備發(fā)送[Hi]和[I am Xiaolin]兩個消息。
在發(fā)送端,當(dāng)我們調(diào)用send函數(shù)完成數(shù)據(jù)“發(fā)送”后,數(shù)據(jù)并沒有真正從網(wǎng)絡(luò)上發(fā)送出去,只是從應(yīng)用程序拷貝到了操作系統(tǒng)的內(nèi)核協(xié)議棧中。
至于什么時候真正被發(fā)送,取決于發(fā)送窗口、擁塞窗口以及當(dāng)前發(fā)送緩沖區(qū)的大小等條件。也就是說,我們不能認為每次send調(diào)用發(fā)送的數(shù)據(jù),都會作為一個完整的消息被發(fā)出。
如果考慮實際網(wǎng)絡(luò)傳輸過程中的各種影響,假設(shè)發(fā)送端陸續(xù)調(diào)用send函數(shù)先后發(fā)送[Hi]和[I am Xiaolin]報文,那么實際的發(fā)送情況可能是以下幾種:
1. 兩個消息被分到同一個TCP報文
2.?[I am Xiaolin]報文的部分隨[Hi]在一個TCP報文中發(fā)送出去
3.?[Hi]的部分隨[I am Xiaolin]報文中發(fā)送出去
因此,不能認為一個用戶消息對應(yīng)一個TCP報文,正因為這樣,TCP是面向字節(jié)流的協(xié)議。
當(dāng)兩個消息的某個部分內(nèi)容被分到同一個TCP報文時,就是常說的TCP粘包問題,這時,接收方不知道消息的邊界的話,是無法讀出有效消息的。
如何解決粘包
粘包的問題出現(xiàn)是因為不知道一個用戶消息的邊界在哪,如果知道了邊界在哪,接收方就可以通過邊界來劃分出有效的用戶消息。文章來源:http://www.zghlxwxcb.cn/news/detail-599671.html
一般有三種方式:文章來源地址http://www.zghlxwxcb.cn/news/detail-599671.html
- 固定長度的消息
- 特殊字符作為邊界
- 自定義消息結(jié)構(gòu)
到了這里,關(guān)于(學(xué)習(xí)筆記)如何理解TCP是面向字節(jié)流的協(xié)議,UDP是面向報文的協(xié)議?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!