t-io網絡編程基礎知識介紹

一、應用層和傳輸層

以http協(xié)議為例,我們在訪問一個網站時,瀏覽器會通過TCP協(xié)議發(fā)送如下字符串到服務器的應用層:

GET /test/abtest HTTP/1.1

Host: 127.0.0.1

Connection: keep-alive

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

Cookie: PHPSESSID=970260278652571648

程序調試截圖(tio的HttpRequest.toString())

這些字符串就是應用層數據,應用層數據是按照一定格式來組織的,這個格式就是應用層協(xié)議,譬如http協(xié)議。

傳輸層在往應用層傳遞數據時,并不保證每次傳遞的數據是一個完整的應用層數據包(以http協(xié)議為例,就是并不保證應用層收到的數據剛好可以組成一個http包),這就是我們經常提到的半包和粘包。傳輸層只負責傳遞byte[]數據,應用層需要自己對byte[]數據進行解碼,以http協(xié)議為例,就是把byte[]解碼成http協(xié)議格式的字符串。

具體請參考:https://www.tiocloud.com/doc/tio/80

二、ByteBuffer

引言

ByteBuffer是nio/aio編程所必須掌握的一個數據結構,也是掌握tio所必須要學會的基礎知識。

設想你不懂Map,不懂List,不懂Set,那么你在編程領域將會一事無成,同樣的道理,如果你不懂ByteBuffer,你無法在nio/aio編程領域立足

初識ByteBuffer

我們可以把bytebuffer理解成如下幾個屬性組成的一個數據結構

byte[] bytes: 用來存儲數據

int capacity: 用來表示bytes的容量,那么可以想像capacity就等于bytes.size(),此值在初始化bytes后,是不可變的。

int limit: 用來表示bytes實際裝了多少數據,可以容易想像得到limit <= capacity,此值是可靈活變動的

int position: 用來表示在哪個位置開始往bytes寫數據或是讀數據,此值是可靈活變動的

一圖感知一下ByteBuffer

具體請參考:https://www.tiocloud.com/doc/tio/83

創(chuàng)建ByteBuffer

ByteBuffer.allocate(int cap)即可創(chuàng)建一個指定容器大小的ByteBuffer,見圖

往ByteBuffer中寫入數據

調用ByteBuffer.put(byte b)即可ByteBuffer中寫入一個字節(jié),見圖

從ByteBuffer讀取數據

對于剛剛寫好的bytebuffer,我們要讀取它的內容,需要先設置一下position和limit,否則讀的位置就不對

接下來調用ByteBuffer.get()即可讀取一個字節(jié),在讀取數據的同時,ByteBuffer的position也會跟關位移,見圖

三、半包和粘包:正確斷句才能溝通

半包

顧名思義,就是收到了半個包,這個時候不足以組成一個應用層的包。就像你要對你喜歡的人說“我喜歡你”,但是因為喝水咽著了,第一次只說了“我”字,第二次說了個“喜”字,第三個次了個“歡你”,那么就發(fā)生了半包問題,對方只有等待你說完這4個字后才知道你是想說“我喜歡你”!

用http協(xié)議為例,展示半包場景

粘包

粘包與半包相反,就是把多個想說的話,一口氣說完了,對方反應不過來,得把你的話拆開一條一條地理解

用http協(xié)議為例,展示粘包場景

、

說明:http協(xié)議是一來一回的,所以正常場景是不會有粘包的,但pipeline模式下是允許一方連續(xù)發(fā)多個請求的,所以會有粘包產生

為何坑人無數

初涉網絡編程的同學,往往認為每次收到的數據剛好是一個完整的數據包

于是當網絡不好,或是消息包過大時,半包的情況就發(fā)生了,而程序并沒有考慮到半包的情況,結果就是解碼失敗,導致消息丟失

當通信的對方把多條業(yè)務數據包放在一個TCP包中發(fā)過來時,粘包就產生了,而程序沒有考慮到一次TCP收包會收到多個業(yè)務包,從而解析到第一個業(yè)務包后把后面的業(yè)務包丟棄了

百度一下半包粘包,一定會搜到很多記錄,這也證明這倆貨確實坑人無數,所以看完本節(jié)內容,你還會繼續(xù)犯半包粘包的錯嗎?

具體請參考:https://www.tiocloud.com/doc/tio/84

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容