欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

常見NIO開源框架(MINA、xSocket)學(xué)習(xí) (轉(zhuǎn)自j

系統(tǒng) 1939 0

http://unbounder.iteye.com/blog/481396

http://unbounder.iteye.com/blog/481668

?

?

基于io包的阻塞式socket通信代碼簡單,在連接數(shù)很少的情況下是一個不錯的選擇。不過實際應(yīng)用中一個socket服務(wù)器采用傳統(tǒng)的阻塞式socket方式通信可能會是一場災(zāi)難,一路socket同時進行讀寫操作可能就需要兩條線程,如果需要并發(fā)一百路socket(這個量其實很小了),可能就是兩百條線程,大概幾分鐘后cpu占用率就是高居不下了。?

基于原生nio的socket通信時一種很好的解決方案,基于事件的通知模式使得多并發(fā)時不用維持高數(shù)量的線程,高并發(fā)的socket服務(wù)器的java實現(xiàn)成為現(xiàn)實。不過原生nio代碼十分復(fù)雜,無論編寫還是修改都是一件頭疼的事?!捌帘蔚讓拥姆爆嵐ぷ?,讓程序員將注意力集中于業(yè)務(wù)邏輯本身”,有需求就有生產(chǎn)力進步,于是各式各樣的nio框架涌現(xiàn)而出,而筆者使用到的是其中最常見的兩種:xSocket和MINA。?

1 xsocket框架 ?

官網(wǎng):http://xsocket.sourceforge.net/?

xSocket是一套非常簡潔的nio框架,利用這套框架,你可以在完全不了解nio的情況下設(shè)計出高并發(fā)的socket服務(wù)器。?
server端代碼:?

Java代碼?? 收藏代碼
  1. public ? class ?ProjectServer? extends ?Thread?{??
  2. ??????
  3. ???? private ? static ? final ? int ?PORT= 9099 ;??
  4. ??????
  5. ???? public ? void ?run()?{??
  6. ????????IServer?srv?=? null ;??
  7. ???????? try ?{??
  8. ???????????? //建立handler ??
  9. ????????????srv?=? new ?Server(PORT,? new ?ProjectHandle());??
  10. ????????}? catch ?(UnknownHostException?e)?{??
  11. ???????????? //?TODO?Auto-generated?catch?block ??
  12. ????????????e.printStackTrace();??
  13. ????????}? catch ?(IOException?e)?{??
  14. ???????????? //?TODO?Auto-generated?catch?block ??
  15. ????????????e.printStackTrace();??
  16. ????????}??
  17. ???????? //服務(wù)器運行 ??
  18. ????????srv.run();??
  19. ????????System.out.println( "The?ProjectServer?start?on?port:?" +PORT);??
  20. ????}??
  21. ??????
  22. ???? public ? static ? void ?main(String[]?args)?{??
  23. ????????ProjectServer?projectServer?=? new ?ProjectServer();??
  24. ????????projectServer.start();??
  25. ????}??
  26. }??

handler代碼?
Java代碼?? 收藏代碼
  1. public ? class ?ProjectHandle? implements ?IDataHandler,?IConnectHandler,??
  2. ????????IDisconnectHandler?{??
  3. ???? /*?處理連接建立事件?*/ ??
  4. ???? @Override ??
  5. ???? public ? boolean ?onConnect(INonBlockingConnection?nbc)? throws ?IOException,??
  6. ????????????BufferUnderflowException,?MaxReadSizeExceededException?{??
  7. ???????? //?TODO?Auto-generated?method?stub ??
  8. ????????System.out.println(nbc.getId()?+? "is?connect!" );??
  9. ???????? return ? true ;??
  10. ????}??
  11. ??
  12. ???? /*?處理連接斷開事件?*/ ??
  13. ???? @Override ??
  14. ???? public ? boolean ?onDisconnect(INonBlockingConnection?nbc)? throws ?IOException?{??
  15. ???????? //?TODO?Auto-generated?method?stub ??
  16. ????????System.out.println(nbc.getId()?+? "is?disconnect!" );??
  17. ???????? return ? true ;??
  18. ????}??
  19. ??
  20. ???? /*?處理接受數(shù)據(jù)事件?*/ ??
  21. ???? @Override ??
  22. ???? public ? boolean ?onData(INonBlockingConnection?nbc)? throws ?IOException,??
  23. ????????????BufferUnderflowException,?ClosedChannelException,??
  24. ????????????MaxReadSizeExceededException?{??
  25. ???????? //?TODO?Auto-generated?method?stub ??
  26. ????????String?str?=?nbc.readStringByDelimiter( "\0" );??
  27. ????????System.out.println(str);??
  28. ???????? return ? true ;??
  29. ????}??
  30. }??

這里我們以"\0"為間隔讀取數(shù)據(jù),xSocket還提供按照長度讀取以及全部讀取到一個ByteBuffer幾種讀取數(shù)據(jù)的方式,如果傳遞過程中采取byte數(shù)組格式,在接受數(shù)據(jù)時還可以使用xSocket自帶的工具類DataConverter進行轉(zhuǎn)化。譬如接收數(shù)據(jù)時如此操作:?
Java代碼?? 收藏代碼
  1. ByteBuffer?copyBuffer?=?ByteBuffer.allocate( 20000 );??
  2. nbc.read(copyBuffer);??
  3. copyBuffer.flip();??
  4. String?str?=?DataConverter.toString(copyBuffer,? "utf-8" );??


就可以將二進制格式的傳輸內(nèi)容還原為原始字符串了。?

需要說明的是雖然xSocket代碼簡單、開發(fā)快捷,但是由于太“上層”了,所以很多地方不利于coder自己控制。譬如socket通信中一個很常見的“半包連包”問題用xsocket處理起來就會很麻煩,而且如果傳輸協(xié)議是經(jīng)過特殊設(shè)計的,xsocket也無法像mina那樣自己編寫解碼器。當然如果你不是特別計較這些方面,那么非常適于上手的xSocket就是適合你的nio框架。?

?

?

3 MINA ?
項目主頁:http://mina.apache.org/?

閑話不說,上代碼?

Java代碼?? 收藏代碼
  1. public ? class ?Server? extends ?Thread?{??
  2. ???? private ? static ? final ? int ?PORT?=? 23 ;??
  3. ??
  4. ???? public ? void ?run()?{??
  5. ????????IoAcceptor?acceptor?=? new ?NioSocketAcceptor();??
  6. ????????acceptor.setHandler( new ?TestHandler());??
  7. ????????acceptor.getFilterChain().addLast( "codec" ,??
  8. ???????????????? new ?ProtocolCodecFilter( new ?TextLineCodecFactory()));??
  9. ????????acceptor.getSessionConfig().setReadBufferSize( 2048 );??
  10. ????????acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,? 10 );??
  11. ???????? try ?{??
  12. ????????????acceptor.bind( new ?InetSocketAddress(PORT));??
  13. ????????}? catch ?(IOException?e)?{??
  14. ???????????? //?TODO?Auto-generated?catch?block ??
  15. ????????????e.printStackTrace();??
  16. ????????}??
  17. ????????System.out.println( "The?ProjectServer?start?on?port:?" ?+?PORT);??
  18. ????}??
  19. ??
  20. ???? public ? static ? void ?main(String[]?args)?{??
  21. ????????Server?server?=? new ?Server();??
  22. ????????server.start();??
  23. ????}??
  24. }??


Java代碼?? 收藏代碼
  1. public ? class ?TestHandler? extends ?IoHandlerAdapter?{??
  2. ??
  3. ???? @Override ??
  4. ???? public ? void ?exceptionCaught(IoSession?session,?Throwable?cause)??
  5. ???????????? throws ?Exception?{??
  6. ???????? //?TODO?Auto-generated?method?stub ??
  7. ????????session.close( true );??
  8. ????}??
  9. ??
  10. ???? @Override ??
  11. ???? public ? void ?sessionCreated(IoSession?session)? throws ?Exception?{??
  12. ???????? //?TODO?Auto-generated?method?stub ??
  13. ????????System.out.println( "the?new?session?is?connecting" );??
  14. ????}??
  15. ??
  16. ???? @Override ??
  17. ???? public ? void ?messageReceived(IoSession?session,?Object?message)??
  18. ???????????? throws ?Exception?{??
  19. ???????? //?TODO?Auto-generated?method?stub ??
  20. ????????String?str?=?message.toString();??
  21. ????????System.out.println(str);??
  22. ????}??
  23. }??

最簡單的一個mina服務(wù)器實現(xiàn),telnet就可以看到效果。?
稍微解釋一下?
mina的實現(xiàn)主要在于給IoAcceptor增加過濾器?
new ProtocolCodecFilter(new TextLineCodecFactory()):這是一個解碼器,可以自己實現(xiàn)ProtocolCodecFactory接口編寫特定的解碼器。不過注意一下,解碼器必須和編碼器同時使用,服務(wù)器端實現(xiàn)特定解碼器的同時需要客戶端應(yīng)用特定編碼。?
常用過濾器還有日志LoggingFilter()等,具體可以查看api。?

這里筆者想說的是對于一般的socket服務(wù)器,可能客戶端并不會使用mina,譬如j2me或者干脆是一個c++的socket請求,此時我們上面的demo將毫無作用,具體來說就是解碼過濾器失效。在實際應(yīng)用中,我們一般是這樣的處理的:?

Java代碼?? 收藏代碼
  1. public ? class ?Server? extends ?Thread?{??
  2. ???? private ? static ? final ? int ?PORT?=? 11001 ;??
  3. ??
  4. ???? public ? void ?run()?{??
  5. ????????IoAcceptor?acceptor?=? new ?NioSocketAcceptor();??
  6. ????????acceptor.setHandler( new ?TestHandler());??
  7. ????????????acceptor.getFilterChain().addLast( "ddd" ,? new ?StreamWriteFilter());??
  8. ????????acceptor.getSessionConfig().setReadBufferSize( 2048 );??
  9. ????????acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,? 10 );??
  10. ???????? try ?{??
  11. ????????????acceptor.bind( new ?InetSocketAddress(PORT));??
  12. ????????}? catch ?(IOException?e)?{??
  13. ???????????? //?TODO?Auto-generated?catch?block ??
  14. ????????????e.printStackTrace();??
  15. ????????}??
  16. ????????System.out.println( "The?ProjectServer?start?on?port:?" ?+?PORT);??
  17. ????}??
  18. ??
  19. ???? public ? static ? void ?main(String[]?args)?{??
  20. ????????Server?server?=? new ?Server();??
  21. ????????server.start();??
  22. ????}??
  23. }??

注意我們并沒有再使用 acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory())); ?
而是 acceptor.getFilterChain().addLast("ddd", new StreamWriteFilter()); ?
這個過濾器是直接對寫入流操作,即原始的數(shù)據(jù)流?

handler端代碼也要修改?
Java代碼?? 收藏代碼
  1. public ? class ?TestHandler? extends ?IoHandlerAdapter?{??
  2. ??
  3. ???? @Override ??
  4. ???? public ? void ?exceptionCaught(IoSession?session,?Throwable?cause)??
  5. ???????????? throws ?Exception?{??
  6. ???????? //?TODO?Auto-generated?method?stub ??
  7. ????????session.close( true );??
  8. ????}??
  9. ??
  10. ???? @Override ??
  11. ???? public ? void ?sessionCreated(IoSession?session)? throws ?Exception?{??
  12. ???????? //?TODO?Auto-generated?method?stub ??
  13. ????????System.out.println( "the?new?session?is?connecting" );??
  14. ????}??
  15. ??
  16. ???? @Override ??
  17. ???? public ? void ?messageReceived(IoSession?session,?Object?message)??
  18. ???????????? throws ?Exception?{??
  19. ???????? //?TODO?Auto-generated?method?stub ??
  20. ??
  21. ????????IoBuffer?buffer=(IoBuffer)message;??
  22. ????????ByteBuffer?bf=?buffer.buf();??
  23. ???????? byte []?tempBuffer= new ? byte [bf.limit()];??
  24. ????????bf.get(tempBuffer);??
  25. ????????String?str= new ?String(tempBuffer);??
  26. ????????System.out.println(str);??
  27. ????}??
  28. }??

注意這段?
Java代碼?? 收藏代碼
  1. IoBuffer?buffer=(IoBuffer)message;??
  2. ByteBuffer?bf=?buffer.buf();??
  3. byte []?tempBuffer= new ? byte [bf.limit()];??
  4. bf.get(tempBuffer);??
  5. String?str= new ?String(tempBuffer);??
  6. System.out.println(str);??

將原始的數(shù)據(jù)流還原為字符串,如果傳輸協(xié)議不是字符串而是byte數(shù)組,就直接對tempBuffer操作即可。?

?

?

常見NIO開源框架(MINA、xSocket)學(xué)習(xí) (轉(zhuǎn)自javaeye博客)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品在线一区 | 日本高清成人 | 91成人小视频 | 一区二区三区四区在线 | 欧美精品二区 | 精品国产一区二区三区免费 | 羞羞电影在线观看 | 小明成人永久视频在线观看 | 国产人成| 亚洲欧美一区二区三区国产精品 | 99亚洲精品| 久久夜色精品国产 | 国产www视频 | 韩国三级午夜理伦三级三 | 中文字幕日本电影 | 日本v在线 | 91短视频免费版 | 欧美一区二区免费电影 | 99热视| 高清中文字幕免费观在线 | 午夜99 | 日韩中文欧美 | 精品亚洲成a人片在线观看 在线看片h站 | 91精品天美精东蜜桃传媒免费 | 国产精品中文在线 | 一级黄色毛片子 | 日产国产精品久久久久久 | 日韩在线精品视频 | 日日夜夜天天 | 欧美a∨ | 国产亚洲精品久久久久婷婷图片 | 91欧美精品激情在线观看 | 一本到在线观看视频不卡 | 久久国产成人 | 99在线精品免费视频九九视 | 一级毛片特级毛片免费的 | 久久久www视频 | 97碰碰碰 | 久久99热这里只频精品6中文字幕 | 亚洲日韩色图 | 久久久精|