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

常見NIO開源框架(MINA、xSocket)學習 (轉自j

系統 1864 0

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

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

?

?

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

基于原生nio的socket通信時一種很好的解決方案,基于事件的通知模式使得多并發時不用維持高數量的線程,高并發的socket服務器的java實現成為現實。不過原生nio代碼十分復雜,無論編寫還是修改都是一件頭疼的事。“屏蔽底層的繁瑣工作,讓程序員將注意力集中于業務邏輯本身”,有需求就有生產力進步,于是各式各樣的nio框架涌現而出,而筆者使用到的是其中最常見的兩種:xSocket和MINA。?

1 xsocket框架 ?

官網:http://xsocket.sourceforge.net/?

xSocket是一套非常簡潔的nio框架,利用這套框架,你可以在完全不了解nio的情況下設計出高并發的socket服務器。?
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. ???????? //服務器運行 ??
  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. ???? /*?處理接受數據事件?*/ ??
  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"為間隔讀取數據,xSocket還提供按照長度讀取以及全部讀取到一個ByteBuffer幾種讀取數據的方式,如果傳遞過程中采取byte數組格式,在接受數據時還可以使用xSocket自帶的工具類DataConverter進行轉化。譬如接收數據時如此操作:?
Java代碼?? 收藏代碼
  1. ByteBuffer?copyBuffer?=?ByteBuffer.allocate( 20000 );??
  2. nbc.read(copyBuffer);??
  3. copyBuffer.flip();??
  4. String?str?=?DataConverter.toString(copyBuffer,? "utf-8" );??


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

需要說明的是雖然xSocket代碼簡單、開發快捷,但是由于太“上層”了,所以很多地方不利于coder自己控制。譬如socket通信中一個很常見的“半包連包”問題用xsocket處理起來就會很麻煩,而且如果傳輸協議是經過特殊設計的,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服務器實現,telnet就可以看到效果。?
稍微解釋一下?
mina的實現主要在于給IoAcceptor增加過濾器?
new ProtocolCodecFilter(new TextLineCodecFactory()):這是一個解碼器,可以自己實現ProtocolCodecFactory接口編寫特定的解碼器。不過注意一下,解碼器必須和編碼器同時使用,服務器端實現特定解碼器的同時需要客戶端應用特定編碼。?
常用過濾器還有日志LoggingFilter()等,具體可以查看api。?

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

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()); ?
這個過濾器是直接對寫入流操作,即原始的數據流?

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);??

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

?

?

常見NIO開源框架(MINA、xSocket)學習 (轉自javaeye博客)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 美女毛片免费 | 亚洲综合精品一区 | 亚洲高清专区 | 久草在线久草在线 | 色姑娘桃花网 | 午夜国产精品久久久久 | 国产视频一区二区三区四区 | 久在线观看 | 欧美成人在线视频 | 国产区精品 | 精品一区二区三区的国产在线观看 | 中文乱码在线观看 | 亚洲综合狠狠 | 亚洲国产精品视频在线观看 | www.色综合 | 中文精品久久久久中文 | 伊人网色 | 免费h片网站 | 久热草视频 | 91中文| 九九亚洲综合精品自拍 | 亚洲国产精品乱码在线观看97 | 久久久久久国产视频 | 婷婷激情视频 | 国产一区二区三区免费在线视频 | 日韩精品视频在线观看免费 | 久久不卡一区二区三区 | 日本天天谢天天要天天爱 | 国产免费久久精品丫丫 | 欧美成年黄网站色视频 | 欧美综合图区 | 欧美成人xx免费视频 | 国产精品福利视频主播真会玩 | 欧美日韩顶级毛片www免费看 | 伊人久久一本大道 | 国产欧美综合在线一区二区三区 | 久青草影院在线观看国产 | 老司机午夜精品视频播放 | 亚洲在线精品视频 | 亚州激情视频在线播放 | 欧美日韩高清一区二区三区 |