亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

基于定長(zhǎng)消息的java nio半包粘包處理

Loong_T / 2322人閱讀

摘要:接收方只需要等待,直到讀到確定數(shù)量的字節(jié),然后處理即可。而這個(gè)字節(jié)流的前個(gè)字節(jié)用于表示對(duì)象的長(zhǎng)度,接下來(lái)的字節(jié)就是傳輸?shù)膶?duì)象的字節(jié)流,最后不夠最大長(zhǎng)度的用任意字節(jié)進(jìn)行填充即可。

什么是tcp半包粘包?
簡(jiǎn)單來(lái)講就是接收到的tcp包并不一定是一個(gè)完整的包。
它可能是1個(gè)包的一部分,也可能是多個(gè)完整包加上1個(gè)包的一部分。
為什么?
因?yàn)閠cp的定義是面向字節(jié)流的傳輸協(xié)議,所以操作系統(tǒng)實(shí)現(xiàn)這個(gè)協(xié)議的時(shí)候,只保證字節(jié)的正確傳輸,而至于字節(jié)的應(yīng)用層語(yǔ)義(可能這個(gè)字節(jié)是個(gè)分隔符,也可能這個(gè)字節(jié)和周?chē)?個(gè)字節(jié)組成一個(gè)int,代表類(lèi)的某個(gè)字段),操作系統(tǒng)是不管的。
比如下面這個(gè)例子(基于java):

public class Account {
    private int accountnum;
    private double balance;
    private int num;
}

要傳輸這個(gè)Account對(duì)象,實(shí)際上就是傳輸它的三個(gè)字段accountnum,balance和num,它們的大小分別是4,8,4個(gè)字節(jié)。當(dāng)傳輸時(shí),實(shí)現(xiàn)tcp協(xié)議的系統(tǒng)只負(fù)責(zé)把這16個(gè)字節(jié)傳輸?shù)浇邮辗?,而不知道這些字節(jié)的含義。比如前4個(gè)字節(jié)是accountnum,然而這是應(yīng)用層的語(yǔ)義,實(shí)現(xiàn)tcp協(xié)議的系統(tǒng)并不知道,也不需要知道,因?yàn)閠cp規(guī)范里就沒(méi)規(guī)定需要知道上層的語(yǔ)義。
那么接收方如何接收呢?
對(duì)于這個(gè)例子實(shí)在是太簡(jiǎn)單了,接收方只需要每次都接收16個(gè)字節(jié)就能保證每一次都能得到一個(gè)完整的Account對(duì)象,連分隔符都不需要。在已知確定傳輸對(duì)象長(zhǎng)度(字節(jié)數(shù)目)的時(shí)候:

即使接收到的tcp包并不一定是一個(gè)完整的包。
接收方只需要等待,直到讀到確定數(shù)量的字節(jié),然后處理即可。
比如現(xiàn)在只傳輸了4個(gè)字節(jié),我們知道16個(gè)字節(jié)才能組成完整的Account對(duì)象,那么再讀12個(gè)字節(jié)后進(jìn)行處理即可。

這個(gè)例子有什么意義?
根據(jù)這個(gè)例子受到啟發(fā),只要傳輸對(duì)象的長(zhǎng)度是確定的,那么接收端很容易就能夠?qū)鬏攲?duì)象進(jìn)行解析(就是處理tcp粘包半包)。
然而對(duì)象的長(zhǎng)度是確定的嗎?往往都不是,比如一個(gè)上面的對(duì)象現(xiàn)在加一個(gè)String類(lèi)型的成員字段,這個(gè)String字段變成字節(jié)的時(shí)候長(zhǎng)度就是未知的,但這并不影響我們把它變成定長(zhǎng)的對(duì)象。
HOW?
設(shè)置最大傳輸長(zhǎng)度,每次都接收最大傳輸長(zhǎng)度的字節(jié)流。而這個(gè)字節(jié)流的前4個(gè)字節(jié)用于表示對(duì)象的長(zhǎng)度,接下來(lái)的字節(jié)就是傳輸?shù)膶?duì)象的字節(jié)流,最后不夠最大長(zhǎng)度的用任意字節(jié)進(jìn)行填充即可。
比如:

public class Account {
private int accountnum;
private double balance;
private int num;
private String extra; 
}

對(duì)于增加了String類(lèi)型字段extra的新Account類(lèi)來(lái)說(shuō),它的一個(gè)對(duì)象長(zhǎng)度是不確定的,現(xiàn)在要傳輸它該怎么辦?設(shè)置最大的長(zhǎng)度為400字節(jié),前4個(gè)字節(jié)存儲(chǔ)實(shí)例對(duì)象的長(zhǎng)度x,之后的x個(gè)字節(jié)為對(duì)象,最后沒(méi)用到的位置用0x0(也就是0)來(lái)填充。比如下圖所示:

需要注意的是,前四個(gè)字節(jié)只是字節(jié),并不是x,需要把這4個(gè)字節(jié)轉(zhuǎn)成int類(lèi)型的變量,然后這個(gè)int變量對(duì)應(yīng)的10進(jìn)制數(shù)是x。
這個(gè)方式看起來(lái)具有很明顯的局限性?
長(zhǎng)度是有限制的?比如一次只能傳輸最多400-4=396個(gè)字節(jié)的對(duì)象?
但是可以把超大的對(duì)象再次分開(kāi),每一次都只傳輸最大包(400)長(zhǎng)度,然后再拼接即可解決。
比如現(xiàn)在設(shè)計(jì)這400個(gè)字節(jié)的存儲(chǔ)格式是這樣的:
前4個(gè)字節(jié)存儲(chǔ)這個(gè)對(duì)象總共被分成幾個(gè)最大傳輸?shù)陌?,接著?個(gè)字節(jié)存儲(chǔ)這是第幾個(gè),然后是長(zhǎng)度,然后是內(nèi)容,最后是填充。

這樣看起來(lái)最大長(zhǎng)度就解決了。
然而。。?;趈ava nio的傳輸適合傳輸大文件(巨長(zhǎng)的字節(jié)流)嗎?
nio是什么原理?
是I/O多路復(fù)用,簡(jiǎn)單來(lái)講就是我有一個(gè)叫做選擇器(Selector)的類(lèi)不斷輪詢不同的連接(Socket)的i/o事件,發(fā)現(xiàn)了i/o事件就處理,處理時(shí)可以用Selector所在的線程,也可以另開(kāi)啟一個(gè)線程。如果要用Selector的線程處理i/o事件,那么i/o的操作時(shí)間必須很短,否則可能會(huì)丟失消息,而如果開(kāi)啟一個(gè)線程,i/o的時(shí)間也應(yīng)該很短。why?因?yàn)槿绻鹖/o時(shí)間很長(zhǎng),并且線程很多,那么就退化成了bio的模型。。。那么就沒(méi)必要用nio了。。。
歸結(jié)起來(lái)就是nio就不適合多用戶傳輸大文件,否則必然退化為bio模型。
所以實(shí)際上不要考慮這種大文件的傳輸,如果要傳輸大文件還是用bio模型比較好,并且在bio的傳輸模式下java提供了對(duì)象的序列化和反序列化,這樣都不需要我們定義長(zhǎng)度字段了。

具體的代碼
參考:https://github.com/ItCrazyer/...

說(shuō)明一點(diǎn)的是,這個(gè)例子里傳輸?shù)膶?duì)象是不定長(zhǎng)的字符串,不是一個(gè)定義的類(lèi)(不是像上面的Account這種),并且使用了SelectionKey對(duì)象的attachment方法,來(lái)暫存數(shù)據(jù),暫存數(shù)據(jù)存儲(chǔ)在TempData這個(gè)類(lèi)的對(duì)象里,為什么?
因?yàn)殡m然我們知道確定的長(zhǎng)度(比如是600),并且據(jù)此處理定長(zhǎng)的數(shù)據(jù),但是一次傳來(lái)的數(shù)據(jù)很可能是好幾個(gè)定長(zhǎng)的數(shù)據(jù)包,而且每一次我們都必須讀完,比如傳來(lái)了1300字節(jié)的數(shù)據(jù),就必須1300字節(jié)都讀完,不能這一次i/o事件我只讀600,然后下一次i/o事件在讀接下來(lái)的700個(gè)字節(jié),那是沒(méi)辦法做到的,因?yàn)閕/o響應(yīng)的是這一次可讀,并不響應(yīng)你還有數(shù)據(jù),所以這次不讀完下次就沒(méi)有了。。。

不過(guò)經(jīng)過(guò)我測(cè)試。。。沒(méi)有讀完的數(shù)據(jù)再下一次仍然可以讀取到,并不會(huì)因?yàn)檫@次沒(méi)讀完下一次就沒(méi)了。。所以不加緩存處理也沒(méi)問(wèn)題?。?!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72139.html

相關(guān)文章

  • 徹底理解Netty,這一篇文章就夠了

    摘要:如果什么事都沒(méi)得做,它也不會(huì)死循環(huán),它會(huì)將線程休眠起來(lái),直到下一個(gè)事件來(lái)了再繼續(xù)干活,這樣的一個(gè)線程稱之為線程。而請(qǐng)求處理邏輯既可以使用單獨(dú)的線程池進(jìn)行處理,也可以跟放在讀寫(xiě)線程一塊處理。 Netty到底是什么 從HTTP說(shuō)起 有了Netty,你可以實(shí)現(xiàn)自己的HTTP服務(wù)器,F(xiàn)TP服務(wù)器,UDP服務(wù)器,RPC服務(wù)器,WebSocket服務(wù)器,Redis的Proxy服務(wù)器,MySQL的P...

    yy13818512006 評(píng)論0 收藏0
  • 使用 LineBasedFrameDecoder 和 StringDecoder 解決半包粘包問(wèn)題

    摘要:修改之前的服務(wù)端開(kāi)發(fā)代碼修改為下面代碼綁定端口同步等待成功等待服務(wù)端監(jiān)聽(tīng)端口關(guān)閉主要修改了和方法和原理分析的工作原理是它依次遍歷中的可讀字節(jié)判斷看是否有或如果有就以此位置為結(jié)束位置從可讀索引到結(jié)束位置區(qū)間的字節(jié)就組成了一行它是以換行符為結(jié)束 修改之前的 Netty 服務(wù)端開(kāi)發(fā) 代碼, 修改為下面代碼 public class TimeServer { public void ...

    HollisChuang 評(píng)論0 收藏0
  • 簡(jiǎn)易R(shí)PC框架:基于 netty 協(xié)議編解碼

    摘要:概述在簡(jiǎn)易框架需求與設(shè)計(jì)這篇文章中已經(jīng)給出了協(xié)議的具體細(xì)節(jié),協(xié)議類(lèi)型為二進(jìn)制協(xié)議,如下協(xié)議的解碼我們稱為,編碼我們成為,下文我們將直接使用和術(shù)語(yǔ)。直接貼代碼,參考前文提到的協(xié)議格式閱讀以下代碼協(xié)議編碼器 概述 在《簡(jiǎn)易R(shí)PC框架:需求與設(shè)計(jì)》這篇文章中已經(jīng)給出了協(xié)議的具體細(xì)節(jié),協(xié)議類(lèi)型為二進(jìn)制協(xié)議,如下: ---------------------------------------...

    Loong_T 評(píng)論0 收藏0
  • netty

    摘要:設(shè)置每個(gè)數(shù)據(jù)包的大小如個(gè)字節(jié),如果某個(gè)數(shù)據(jù)包不足個(gè)字節(jié)可能會(huì)出現(xiàn)丟包的情況,即該數(shù)據(jù)包未從一個(gè)端到另一個(gè)端,此時(shí)需要用空格或者既定的符號(hào)補(bǔ)充在數(shù)據(jù)包之間使用一些字符進(jìn)行分割如號(hào)之類(lèi)的,解析的時(shí)候先處理掉分隔符再拿到各個(gè)數(shù)據(jù)包就好了。 netty 概念: Netty是由JBOSS提供的一個(gè)java開(kāi)源框架。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開(kāi)發(fā)高性能、高可靠...

    cfanr 評(píng)論0 收藏0
  • Java】幾道讓你拿offer面試題

    摘要:的方法,的默認(rèn)實(shí)現(xiàn)會(huì)判斷是否是類(lèi)型注意自動(dòng)拆箱,自動(dòng)裝箱問(wèn)題。適應(yīng)自旋鎖鎖競(jìng)爭(zhēng)是下的,會(huì)經(jīng)過(guò)用戶態(tài)到內(nèi)核態(tài)的切換,是比較花時(shí)間的。在中引入了自適應(yīng)的自旋鎖,說(shuō)明自旋的時(shí)間不固定,要不要自旋變得越來(lái)越聰明。 前言 只有光頭才能變強(qiáng) 之前在刷博客的時(shí)候,發(fā)現(xiàn)一些寫(xiě)得比較好的博客都會(huì)默默收藏起來(lái)。最近在查閱補(bǔ)漏,有的知識(shí)點(diǎn)比較重要的,但是在之前的博客中還沒(méi)有寫(xiě)到,于是趁著閑整理一下。 文本的...

    張春雷 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<