亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

netty 學(xué)習(xí) FrameDecoder

系統(tǒng) 2481 0

我們接下來就看和業(yè)務(wù)息息相關(guān)的解碼器,首先我們來看FrameDecoder,這個東西應(yīng)該是所有的解碼器都會實現(xiàn)這個,所以我們來重點看一下。

? ? ? ??FrameDecoder產(chǎn)生的根源就是TCP/IP數(shù)據(jù)包的傳輸方式?jīng)Q定的,包在傳輸?shù)倪^程中會分片和重組,

正如javadoc里面所說的:

? ? 客戶端在發(fā)送的時候的序列如下:

+-----+-----+-----+

| ABC | DEF | GHI |

+-----+-----+-----+

服務(wù)器端在接受到后可能會變成下面的序列:

+----+-------+---+---+

| AB | CDEFG | H | I |

+----+-------+---+---+

FrameDecoder幫助我們將接受到的數(shù)據(jù)包整理成有意義的數(shù)據(jù)幀,例如,可以幫助我們將數(shù)據(jù)包整理成

下面的數(shù)據(jù)格式:

+-----+-----+-----+

| ABC | DEF | GHI |

+-----+-----+-----+

我們接下來就看看FrameDecoder的實現(xiàn)吧:

FrameDecoder是繼承SimpleChannelUpstreamHandler的,我們首先來看一下messageReceived的實現(xiàn):

? ? ? ??

Java代碼 ? 收藏代碼
  1. @Override??
  2. ??? public? void?messageReceived(??
  3. ???????????ChannelHandlerContext?ctx,?MessageEvent?e)? throws?Exception?{??
  4. ??
  5. ???????Object?m?=?e.getMessage();??
  6. ??????? if?(!(m? instanceof?ChannelBuffer))?{??
  7. ???????????ctx.sendUpstream(e);??
  8. ??????????? return;??
  9. ???????}??
  10. ??
  11. ???????ChannelBuffer?input?=?(ChannelBuffer)?m;??
  12. ??????? if?(!input.readable())?{??
  13. ??????????? return;??
  14. ???????}??
  15. ??
  16. ???????ChannelBuffer?cumulation?=?cumulation(ctx);??
  17. ??????? if?(cumulation.readable())?{??
  18. ???????????cumulation.discardReadBytes();??
  19. ???????????cumulation.writeBytes(input);??
  20. ???????????callDecode(ctx,?e.getChannel(),?cumulation,?e.getRemoteAddress());??
  21. ???????}? else?{??
  22. ???????????callDecode(ctx,?e.getChannel(),?input,?e.getRemoteAddress());??
  23. ??????????? if?(input.readable())?{??
  24. ???????????????cumulation.writeBytes(input);??
  25. ???????????}??
  26. ???????}??
  27. ???}??

? ? ? ??這個里面首先會檢查input的可讀性,這個比較好理解,關(guān)鍵是cumulation,

我們首先來看一下cumulation的實現(xiàn)吧:

Java代碼 ? 收藏代碼
  1. private?ChannelBuffer?cumulation(ChannelHandlerContext?ctx)?{??
  2. ????????ChannelBuffer?c?=?cumulation;??
  3. ???????? if?(c?==? null)?{??
  4. ????????????c?=?ChannelBuffers.dynamicBuffer(??
  5. ????????????????????ctx.getChannel().getConfig().getBufferFactory());??
  6. ????????????cumulation?=?c;??
  7. ????????}??
  8. ???????? return?c;??
  9. ????}??

? ? ? ??這個函數(shù)很簡單,就是如果cumulation為空的時候初始化一下,如果不為空,就返回。我們得思考一下什么時候cumulation為空,什么時候不為空。我們再回過頭來看一下上面的實現(xiàn)吧。如果cumulation可讀,cumulation.discardReadBytes函數(shù)的作用是將0到readIndex之間的空間釋放掉,將readIndex和writeIndex都重新標(biāo)記一下。然后將讀到的數(shù)據(jù)寫到buffer里面。如果cumulation不可讀,在調(diào)callDecode,如果發(fā)現(xiàn)從不可讀狀態(tài)到可讀狀態(tài),則將讀到的數(shù)據(jù)寫到緩存區(qū)里面。

? ? ? ??我們再來看callDecode的實現(xiàn):

Java代碼 ? 收藏代碼
  1. private? void?callDecode(??
  2. ????????????ChannelHandlerContext?context,?Channel?channel,??
  3. ????????????ChannelBuffer?cumulation,?SocketAddress?remoteAddress)? throws?Exception?{??
  4. ??
  5. ???????? while?(cumulation.readable())?{??
  6. ???????????? int?oldReaderIndex?=?cumulation.readerIndex();??
  7. ????????????Object?frame?=?decode(context,?channel,?cumulation);??
  8. ???????????? if?(frame?==? null)?{??
  9. ???????????????? if?(oldReaderIndex?==?cumulation.readerIndex())?{??
  10. ???????????????????? //?Seems?like?more?data?is?required.??
  11. ???????????????????? //?Let?us?wait?for?the?next?notification.??
  12. ???????????????????? break;??
  13. ????????????????}? else?{??
  14. ???????????????????? //?Previous?data?has?been?discarded.??
  15. ???????????????????? //?Probably?it?is?reading?on.??
  16. ???????????????????? continue;??
  17. ????????????????}??
  18. ????????????}? else? if?(oldReaderIndex?==?cumulation.readerIndex())?{??
  19. ???????????????? throw? new?IllegalStateException(??
  20. ???????????????????????? "decode()?method?must?read?at?least?one?byte?"?+??
  21. ???????????????????????? "if?it?returned?a?frame?(caused?by:?"?+?getClass()?+? ")");??
  22. ????????????}??
  23. ??
  24. ????????????unfoldAndFireMessageReceived(context,?remoteAddress,?frame);??
  25. ????????}??
  26. ??
  27. ???????? if?(!cumulation.readable())?{??
  28. ?????????? this.cumulation?=? null;??
  29. ????????}??
  30. ????}??
  31. ??????

?

?

? ? ? ?這個里面上面是一個循環(huán),首先將讀指針備份一下,decode方法是交個子類實現(xiàn)的一個抽象方這個用來實現(xiàn)具體數(shù)據(jù)分幀的算法,從這個里面看到如果子類沒有讀到一幀數(shù)據(jù),則返回null所以下面有一個判斷,是一點數(shù)據(jù)沒有讀呢,還是讀了一點,如果一點都沒有讀,就不需要再檢測了等下一次messageRecieved進(jìn)行通知,如果發(fā)現(xiàn)讀了一點數(shù)據(jù),就調(diào)用下一次分幀。如果讀了一幀數(shù)據(jù)就發(fā)送一個通知,unfold是針對讀到的循環(huán)數(shù)據(jù)要不要打開的意思。到最后如果發(fā)現(xiàn)不是可讀狀態(tài),

cumulation將會被設(shè)置成null。

?

最后來看一下cleanup的實現(xiàn)

Java代碼 ? 收藏代碼
  1. private? void?cleanup(ChannelHandlerContext?ctx,?ChannelStateEvent?e)??
  2. ???????????? throws?Exception?{??
  3. ???????? try?{??
  4. ????????????ChannelBuffer?cumulation?=? this.cumulation;??
  5. ???????????? if?(cumulation?==? null)?{??
  6. ???????????????? return;??
  7. ????????????}? else?{??
  8. ???????????????? this.cumulation?=? null;??
  9. ????????????}??
  10. ??
  11. ???????????? if?(cumulation.readable())?{??
  12. ???????????????? //?Make?sure?all?frames?are?read?before?notifying?a?closed?channel.??
  13. ????????????????callDecode(ctx,?ctx.getChannel(),?cumulation,? null);??
  14. ????????????}??
  15. ??
  16. ???????????? //?Call?decodeLast()?finally.??Please?note?that?decodeLast()?is??
  17. ???????????? //?called?even?if?there's?nothing?more?to?read?from?the?buffer?to??
  18. ???????????? //?notify?a?user?that?the?connection?was?closed?explicitly.??
  19. ????????????Object?partialFrame?=?decodeLast(ctx,?ctx.getChannel(),?cumulation);??
  20. ???????????? if?(partialFrame?!=? null)?{??
  21. ????????????????unfoldAndFireMessageReceived(ctx,? null,?partialFrame);??
  22. ????????????}??
  23. ????????}? finally?{??
  24. ????????????ctx.sendUpstream(e);??
  25. ????????}??
  26. ????}??

? ??在這個里面一般來說是在socket斷開的時候調(diào)用,這個時候如果發(fā)現(xiàn)buffer還是可讀狀態(tài),還會努力的確保所有的數(shù)據(jù)已經(jīng)被分幀,然后調(diào)用decodeLast

?

===========================================================================================

轉(zhuǎn)自http://blog.csdn.net/xiaolang85/article/details/12621663

netty 學(xué)習(xí) FrameDecoder


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美成人免费tv在线播放 | 精品国产第一国产综合精品 | 九九精品视频在线免费观看 | 女人与女zzzoooxxxx | 日韩一区二区三区视频在线观看 | 羞羞色院91 | 外国成人网在线观看免费视频 | 色香欲综合成人免费视频 | 中文日韩欧美 | 久久久毛片免费全部播放 | 欧美午夜精品 | 国产精品成人免费综合 | 日韩操| 国产成人免费a在线资源 | 91精东果冻蜜桃星空麻豆 | 青青青草视频在线观看 | 成人免费淫片在线费观看 | 欧美色婷婷 | 久热爱免费精品视频在线播放 | 精品国产91乱码一区二区三区 | 久久国产欧美日韩精品 | 国产精品久久久久久永久牛牛 | 老司机福利在线播放 | 岛国不卡 | 偷偷狠狠的日日2020 | 久久久精品免费国产四虎 | 麻豆国内精品欧美在线 | 日日草天天干 | 亚洲视频一区二区三区四区 | 亚洲精品一区二区三区中文字幕 | 四虎永久在线精品影院 | 亚洲羞羞视频 | 国产a不卡片精品免费观看 国产a高清 | 99精品视频只99有精品 | 久久66热re国产毛片基地 | 四虎成人免费网站在线 | 久久综合97色综合网 | 国产一级在线观看www色 | 操片免费| 欧美jizz19性欧美| 最新国产在线视频 |