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

netty 學習 FrameDecoder

系統 2182 0

我們接下來就看和業務息息相關的解碼器,首先我們來看FrameDecoder,這個東西應該是所有的解碼器都會實現這個,所以我們來重點看一下。

? ? ? ??FrameDecoder產生的根源就是TCP/IP數據包的傳輸方式決定的,包在傳輸的過程中會分片和重組,

正如javadoc里面所說的:

? ? 客戶端在發送的時候的序列如下:

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

| ABC | DEF | GHI |

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

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

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

| AB | CDEFG | H | I |

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

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

下面的數據格式:

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

| ABC | DEF | GHI |

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

我們接下來就看看FrameDecoder的實現吧:

FrameDecoder是繼承SimpleChannelUpstreamHandler的,我們首先來看一下messageReceived的實現:

? ? ? ??

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的可讀性,這個比較好理解,關鍵是cumulation,

我們首先來看一下cumulation的實現吧:

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. ????}??

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

? ? ? ??我們再來看callDecode的實現:

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. ??????

?

?

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

cumulation將會被設置成null。

?

最后來看一下cleanup的實現

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斷開的時候調用,這個時候如果發現buffer還是可讀狀態,還會努力的確保所有的數據已經被分幀,然后調用decodeLast

?

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

轉自http://blog.csdn.net/xiaolang85/article/details/12621663

netty 學習 FrameDecoder


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 牛牛影视成人午夜影视 | 精品综合久久久久久99 | 免费视频爱爱 | 伊人99在线| 久久精品国产欧美日韩99热 | 日本一二区视频 | 久草免费在线观看 | 一区二区三区中文国产亚洲 | 精品小视频在线观看 | 四虎影视院| 成人永久免费高清 | 亚洲a网 | 久久最新免费视频 | 九九天天影视 | 免费观看一级特黄欧美大片 | 国产精品日韩欧美 | 欧美特级爽毛片 | 日本一级在线观看视频播放 | 久久这里只有精品18 | 久热官网 | 九九99九九精彩网站 | 黄色在线视频网 | 国产真实伦视频在线观看 | 国产美女流白浆的免费视 | 国产大片中文字幕在线观看 | 亚洲伦理一二三四 | 四虎影院2022 | 亚洲欧美国产18 | 亚洲最大色视频 | 国产自产视频在线观看香蕉 | 亚洲第一免费视频 | 国产一区免费视频 | 亚洲欧洲视频 | 这里是九九伊人 | 中国老妇色xxxxx | 亚洲视频在线播放 | 女人的毛片 | 久久se精品一区二区国产 | 伊人22222 | 精品久久久影院 | 玖玖精品在线视频 |