mina源碼閱讀之編碼與解碼

TCP是一個流協議,所謂流協議就是沒有界限的一串數據,數據之間並沒有分界線,它會根據TCP緩衝區的實際大小進行包的劃分,那麼業務上的一個完整包可能會被TCP拆成多個包進行發送,也有可能把多個小的包封裝成一個大包進行發送,這時候就可能發生拆包與粘包。對於接收端來說,由於數據並沒有界限,接收端不知道到底什麼時候數據算是讀取完,也只能根據緩衝區的大小來進行包的劃分,此時接收端也可能會發生拆包與粘包。
針對TCP流協議的特性,有三種常用的方法可解決拆包與粘包的問題。
1、因爲包與包之間沒有界限纔會導致無法判斷是否讀取到了一個完整的包,因此可在發送端和接收端定義一個相同的分隔符,發送端在發送數據的時候,包與包之間用該分隔符隔開,這樣接收端讀取到對應的分隔符就認爲讀取到了一個完整的包,就可以繼續下一步操作了。
2、消息定長,比如每個報文的大小固定爲200字節,如果不夠空位補齊。
3、在數據中的某個位置使用一個字段,表示數據的長度,類似Http協議中的Content-Length表示消息正文的長度。
發送端使用以上三種方法中的一種來使原本沒界限的數據變的有規律可循,這個過程就是我們常說的編碼。對應的在接收端,根據發送端數據的規律解析數據的過程叫解碼。
mina底層使用的協議就是TCP,TCP傳輸過程中的數據都是二進制數據,服務端和客戶端程序中使用的都是Java對象,那麼必然有一個將Java對象變成二進制數據和將二進制數據解析成Java對象的過程,這個過程中很可能就會出現粘包與拆包的問題。那麼爲了解決TCP通信過程中產生的粘包、拆包問題,需要在發送方就要讓Java對象按照某種規律變成二進制數據,然後接收方根據同樣的規律將二進制數據解析成Java對象,這兩個過程分別對應編碼和解碼過程。
爲了實現在發送數據之前對數據按照某種規律進行編碼,我們需要實現自己的編碼器。在mina中實現編碼器是一件簡單且愉快的事情,我們只需實現ProtocolEncoder接口,但是有更簡便的方法,直接繼承ProtocolEncoderAdapter類,實現encode方法即可。
同理,爲了對接收到的數據按照約定的規律進行解碼,我們需要實現自己的解碼器。在mina中實現解碼器只需實現ProtocolDecoder接口,更簡潔的方法就是繼承ProtocolDecoderAdapter類,實現decode方法即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章