欧美三区_成人在线免费观看视频_欧美极品少妇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條評論
主站蜘蛛池模板: 国产成人微拍精品 | 国产在线小视频 | 日本免费在线 | 亚洲自拍另类 | 色吧综合 | 日韩一区二区免费看 | 国产精品精品 | 青草福利在线 | 日韩成人在线观看 | 欧美成人私人视频88在线观看 | 日韩一区二区精品视频 | 天天干天天干天天干天天干天天干 | 亚洲精品人人 | 日韩中文字幕在线看 | 国产精品免费观看视频 | 日本高清在线观看视频 | 91在线| 欧美在线观看一区 | 国产高清一区二区 | 五月激情综合网 | 国产在线资源 | 国产精品黄视频 | 精品国产18久久久久久二百 | 亚洲精品乱码 | 天天操人人射 | 午夜私人影院粉色视频我要 | 天天摸天天做天天爽在线 | 日本免费在线视频 | 亚洲毛片网站 | 锵锵锵锵锵锵锵锵锵好湿好大 | 国产精品夜色一区二区三区 | 夜夜爽夜夜叫夜夜高潮漏水 | 欧美精品综合在线 | 六月色婷 | 欧美电影在线观看网站 | free-porn-ok| 亚洲欧美综合精品久久成人 | 日韩免费播放 | 一级毛片 在线播放 | 国产高清永久免费 | 亚洲国产精品久久婷婷 |