ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>黄色av网址在线免费观看,中国av一区,欧美最猛性xxxxhttp://www.aygfsteel.com/paulwong/category/53575.htmlzh-cnTue, 14 May 2013 17:15:45 GMTTue, 14 May 2013 17:15:45 GMT60MINA资源http://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.htmlpaulwongpaulwongTue, 14 May 2013 09:41:00 GMThttp://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.htmlhttp://www.aygfsteel.com/paulwong/comments/399270.htmlhttp://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.html#Feedback0http://www.aygfsteel.com/paulwong/comments/commentRss/399270.htmlhttp://www.aygfsteel.com/paulwong/services/trackbacks/399270.html http://yaojialing.iteye.com/category/115609

使用 Apache MINA 2 开发网¾lœåº”ç”?br />http://www.ibm.com/developerworks/cn/java/j-lo-mina2/

直接操作minaçš„IoBuffer‹¹?
http://autumnice.blog.163.com/blog/static/555200201011493410310/

pache mina 学习(f¨¤n)åQˆåä¸€åQ?----状态机åQˆstateMachineåQ?br />http://cages.iteye.com/blog/1530849

˜qç”¨ Apache MINA 2 开发网¾lœè¿ç”?[多图]
http://www.lj8lj8.com/chengxukaifa/Java/338853_13.html




]]>
åŸÞZºŽApache Mina实现的TCP长连接和短连接实ä¾?/title><link>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Sat, 11 May 2013 13:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html</guid><wfw:comment>http://www.aygfsteel.com/paulwong/comments/399155.html</wfw:comment><comments>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/paulwong/comments/commentRss/399155.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/paulwong/services/trackbacks/399155.html</trackback:ping><description><![CDATA[1、前­a€<br /> <br /> Apache MINA是Apache¾l„织的一个优¿U€çš„项目。MINA是Multipurpose Infrastructure for NetworkApplications的羃写。它是一个网¾lœåº”用程序框æžÓž¼Œç”¨æ¥å¸®åŠ©ç”¨æˆ·éžå¸¸æ–¹ä¾¿åœ°å¼€å‘é«˜æ€§èƒ½å’Œé«˜å¯é æ€§çš„¾|‘络应用½E‹åºã€‚在本文中介¾läº† 如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用ã€?br /> <br /> 2、系¾lŸä»‹¾l?br /> <br /> 2.1¾pȝ»Ÿæ¡†æž¶<br /> <br /> 整个¾pȝ»Ÿç”׃¸¤ä¸ªæœåŠ¡ç«¯½E‹åºå’Œä¸¤ä¸ªå®¢æˆïL(f¨¥ng)«¯½E‹åº¾l„成。分别实现TCP长连接和短连接通信ã€?br /> <br /> ¾pȝ»Ÿä¸šåŠ¡é€»è¾‘æ˜¯ä¸€ä¸ªå®¢æˆïL(f¨¥ng)«¯ä¸ŽæœåŠ¡ç«¯å»ºç«‹é•¿è¿žæŽ¥ï¼Œä¸€ä¸ªå®¢æˆïL(f¨¥ng)«¯ä¸ŽæœåŠ¡ç«¯å»ºç«‹çŸ­è¿žæŽ¥ã€‚æ•°æ®ä»ŽçŸ­è¿žæŽ¥å®¢æˆïL(f¨¥ng)«¯¾lè¿‡æœåŠ¡ç«¯å‘é€åˆ°é•¿è¿žæŽ¥å®¢æˆïL(f¨¥ng)«¯åQŒåƈ从长˜qžæŽ¥å®¢æˆ·ç«¯æŽ¥æ”¶å“åº”数据。当收到响应数据后断开˜qžæŽ¥ã€?br /> <br /> ¾pȝ»Ÿæž¶æž„囑֦‚下:(x¨¬)<br /> <br /> <br /> 2.2处理‹¹ç¨‹<br /> <br /> ¾pȝ»Ÿå¤„理‹¹ç¨‹å¦‚下åQ?br /> <br /> 1åQ? 启动服务端程序,监听8001å’?002端口ã€?br /> <br /> 2åQ? 长连接客æˆïL(f¨¥ng)«¯å‘服务端8002端口建立˜qžæŽ¥åQŒæœåŠ¡ç«¯ž®†è¿žæŽ¥å¯¹è±¡ä¿å­˜åˆ°å…׃ín内存中。由于采用长˜qžæŽ¥æ–¹å¼åQŒè¿žæŽ¥å¯¹è±¡æ˜¯å”¯ä¸€çš„ã€?br /> <br /> 3åQ? 短连接客æˆïL(f¨¥ng)«¯å‘服务端8001端口建立˜qžæŽ¥ã€‚徏立连接后创徏一个连接对象ã€?br /> <br /> 4åQ? 短连接客æˆïL(f¨¥ng)«¯˜qžæŽ¥æˆåŠŸåŽå‘é€æ•°æ®ã€‚æœåŠ¡ç«¯æŽ¥æ”¶åˆ°æ•°æ®åŽä»Žå…±äº«å†…å­˜ä¸­å¾—åˆ°é•¿è¿žæŽ¥æ–¹å¼çš„˜qžæŽ¥å¯¹è±¡åQŒä‹É用此对象向长˜qžæŽ¥å®¢æˆ·ç«¯å‘送数据。发送前ž®†çŸ­˜qžæŽ¥å¯¹è±¡è®¾äØ“(f¨´)长连接对象的属性倹{€?br /> <br /> 5åQ? 长连接客æˆïL(f¨¥ng)«¯æŽ¥æ”¶åˆ°æ•°æ®åŽ˜q”回响应数据。服务端从长˜qžæŽ¥å¯¹è±¡çš„属性中取得短连接对象,通过此对象将响应数据发送给短连接客æˆïL(f¨¥ng)«¯ã€?br /> <br /> 6åQ? 短连接客æˆïL(f¨¥ng)«¯æ”¶åˆ°å“åº”数据后,关闭˜qžæŽ¥ã€?br /> <br /> 3、服务端½E‹åº<br /> <br /> 3.1长连接服务端<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaLongConnServer {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8002;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> start()<span style="color: #0000FF; ">throws</span> IOException{<br /> <br /> IoAcceptor acceptor = <span style="color: #0000FF; ">new</span> NioSocketAcceptor();<br /> <br /> <br /> <br /> acceptor.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> acceptor.setHandler(<span style="color: #0000FF; ">new</span> MinaLongConnServerHandler());<br /> <br /> acceptor.getSessionConfig().setReadBufferSize(2048);<br /> <br /> acceptor.bind(<span style="color: #0000FF; ">new</span> InetSocketAddress(PORT));<br /> <br /> System.out.println("Listeningon port " + PORT);<br /> <br /> }<br /> <br /> }<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; ">消息处理</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaLongConnServerHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();<br /> <br /> String clientIp = remoteAddress.getAddress().getHostAddress();<br /> <br /> logger.info("LongConnect Server opened Session ID ="+String.valueOf(session.getId()));<br /> <br /> logger.info("接收来自客户ç«?nbsp;:" + clientIp + "的连æŽ?");<br /> <br /> Initialization init = Initialization.getInstance();<br /> <br /> HashMap<String, IoSession> clientMap =init.getClientMap();<br /> <br /> clientMap.put(clientIp, session);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the long connect server..");<br /> <br /> String expression = message.toString();<br /> <br /> logger.info("Message is:" + expression);<br /> <br /> IoSession shortConnSession =(IoSession) session.getAttribute("shortConnSession");<br /> <br /> logger.info("ShortConnect Server Session ID ="+String.valueOf(shortConnSession.getId()));<br /> <br /> shortConnSession.write(expression);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionIdle(IoSession session, IdleStatus status) {<br /> <br /> logger.info("Disconnectingthe idle.");<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> disconnect an idle client</span><span style="color: #008000; "><br /> </span><br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> close the connection onexceptional situation</span><span style="color: #008000; "><br /> </span><br /> logger.warn(cause.getMessage(), cause);<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> 3.2短连接服务端<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortConnServer {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8001;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> start()<span style="color: #0000FF; ">throws</span> IOException{<br /> <br /> IoAcceptor acceptor = <span style="color: #0000FF; ">new</span> NioSocketAcceptor();<br /> <br /> <br /> <br /> acceptor.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> acceptor.setHandler(<span style="color: #0000FF; ">new</span> MinaShortConnServerHandler());<br /> <br /> acceptor.getSessionConfig().setReadBufferSize(2048);<br /> <br /> acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);<br /> <br /> acceptor.bind(<span style="color: #0000FF; ">new</span> InetSocketAddress(PORT));<br /> <br /> System.out.println("Listeningon port " + PORT);<br /> <br /> }<br /> <br /> }</div> <br /> 消息处理<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortConnServerHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();<br /> <br /> logger.info(remoteAddress.getAddress().getHostAddress());<br /> <br /> logger.info(String.valueOf(session.getId()));<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the short connect server<img src="http://www.aygfsteel.com/Images/dot.gif" alt="" />");<br /> <br /> String expression = message.toString();<br /> <br /> Initialization init = Initialization.getInstance();<br /> <br /> HashMap<String, IoSession> clientMap =init.getClientMap();<br /> <br /> <span style="color: #0000FF; ">if</span> (clientMap == <span style="color: #0000FF; ">null</span> || clientMap.size() == 0) {<br /> <br /> session.write("error");<br /> <br /> } <span style="color: #0000FF; ">else</span> {<br /> <br /> IoSession longConnSession = <span style="color: #0000FF; ">null</span>;<br /> <br /> Iterator<String> iterator =clientMap.keySet().iterator();<br /> <br /> String key = "";<br /> <br /> <span style="color: #0000FF; ">while</span> (iterator.hasNext()) {<br /> <br /> key = iterator.next();<br /> <br /> longConnSession = clientMap.get(key);<br /> <br /> }<br /> <br /> logger.info("ShortConnect Server Session ID :"+String.valueOf(session.getId()));<br /> <br /> logger.info("LongConnect Server Session ID :"+String.valueOf(longConnSession.getId()));<br /> <br /> longConnSession.setAttribute("shortConnSession",session);<br /> <br /> longConnSession.write(expression);<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionIdle(IoSession session, IdleStatus status) {<br /> <br /> logger.info("Disconnectingthe idle.");<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> disconnect an idle client</span><span style="color: #008000; "><br /> </span><br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> close the connection onexceptional situation</span><span style="color: #008000; "><br /> </span><br /> logger.warn(cause.getMessage(), cause);<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> <br /> <br /> 4、客æˆïL(f¨¥ng)«¯½E‹åº<br /> <br /> 4.1长连接客æˆïL(f¨¥ng)«¯<br /> <br /> 使用java.net.Socket来实现向服务端徏立连接。Socket建立后一直保持连接,从服务端接收到数据包后直接将原文˜q”回ã€?br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> TcpKeepAliveClient {<br /> <br /> <span style="color: #0000FF; ">private</span> String ip;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">int</span> port;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> Socket socket = <span style="color: #0000FF; ">null</span>;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">int</span> timeout = 50 * 1000;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> TcpKeepAliveClient(String ip, <span style="color: #0000FF; ">int</span> port) {<br /> <br /> <span style="color: #0000FF; ">this</span>.ip = ip;<br /> <br /> <span style="color: #0000FF; ">this</span>.port = port;<br /> <br /> }<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> receiveAndSend() <span style="color: #0000FF; ">throws</span> IOException {<br /> <br /> InputStream input = <span style="color: #0000FF; ">null</span>;<br /> <br /> OutputStream output = <span style="color: #0000FF; ">null</span>;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">try</span> {<br /> <br /> <span style="color: #0000FF; ">if</span> (socket == <span style="color: #0000FF; ">null</span> || socket.isClosed() || !socket.isConnected()) {<br /> <br /> socket = <span style="color: #0000FF; ">new</span> Socket();<br /> <br /> InetSocketAddress addr = <span style="color: #0000FF; ">new</span> InetSocketAddress(ip, port);<br /> <br /> socket.connect(addr, timeout);<br /> <br /> socket.setSoTimeout(timeout);<br /> <br /> System.out.println("TcpKeepAliveClientnew ");<br /> <br /> }<br /> <br /> <br /> <br /> input = socket.getInputStream();<br /> <br /> output = socket.getOutputStream();<br /> <br /> <br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> read body</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">byte</span>[] receiveBytes = {};<span style="color: #008000; ">//</span><span style="color: #008000; "> æ”¶åˆ°çš„包字节数组</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">while</span> (<span style="color: #0000FF; ">true</span>) {<br /> <br /> <span style="color: #0000FF; ">if</span> (input.available() > 0) {<br /> <br /> receiveBytes = <span style="color: #0000FF; ">new</span> <span style="color: #0000FF; ">byte</span>[input.available()];<br /> <br /> input.read(receiveBytes);<br /> <br /> <br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> send</span><span style="color: #008000; "><br /> </span><br /> System.out.println("TcpKeepAliveClientsend date :" + <span style="color: #0000FF; ">new</span> String(receiveBytes));<br /> <br /> output.write(receiveBytes, 0, receiveBytes.length);<br /> <br /> output.flush();<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> } <span style="color: #0000FF; ">catch</span> (Exception e) {<br /> <br /> e.printStackTrace();<br /> <br /> System.out.println("TcpClientnew socket error");<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> main(String[] args) <span style="color: #0000FF; ">throws</span> Exception {<br /> <br /> TcpKeepAliveClient client = <span style="color: #0000FF; ">new</span> TcpKeepAliveClient("127.0.0.1", 8002);<br /> <br /> client.receiveAndSend();<br /> <br /> }<br /> <br /> <br /> <br /> }</div> <br /> 4.2短连接客æˆïL(f¨¥ng)«¯<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortClient {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8001;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> main(String[] args) <span style="color: #0000FF; ">throws</span> IOException,InterruptedException {<br /> <br /> IoConnector connector = <span style="color: #0000FF; ">new</span> NioSocketConnector();<br /> <br /> connector.getSessionConfig().setReadBufferSize(2048);<br /> <br /> <br /> <br /> connector.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> connector.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> connector.setHandler(<span style="color: #0000FF; ">new</span> MinaShortClientHandler());<br /> <br /> <span style="color: #0000FF; ">for</span> (<span style="color: #0000FF; ">int</span> i = 1; i <= 10; i++) {<br /> <br /> ConnectFuture future = connector.connect(<span style="color: #0000FF; ">new</span> InetSocketAddress("127.0.0.1", PORT));<br /> <br /> future.awaitUninterruptibly();<br /> <br /> IoSession session =future.getSession();<br /> <br /> session.write(i);<br /> <br /> session.getCloseFuture().awaitUninterruptibly();<br /> <br /> <br /> <br /> System.out.println("result=" + session.getAttribute("result"));<br /> <br /> }<br /> <br /> connector.dispose();<br /> <br /> <br /> <br /> }<br /> <br /> }</div> <br /> 消息处理<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortClientHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter{<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> MinaShortClientHandler() {<br /> <br /> <br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the client..");<br /> <br /> logger.info("Message is:" + message.toString());<br /> <br /> session.setAttribute("result", message.toString());<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> 5、æ€È»“<br /> <br /> 通过本文中的例子åQŒApache Mina在服务端可实现TCP协议长连接和短连接。在客户端只实现了短˜qžæŽ¥æ¨¡å¼åQŒé•¿˜qžæŽ¥æ¨¡å¼ä¹Ÿæ˜¯å¯ä»¥å®žçŽ°çš„ï¼ˆåœ¨æœ¬æ–‡ä¸­˜q˜æ˜¯é‡‡ç”¨ä¼ ç»Ÿçš„java Socket方式åQ‰ã€‚两个服务端之间通过å…׃ín内存的方式来传递连接对象也许有更好的实现方式ã€?img src ="http://www.aygfsteel.com/paulwong/aggbug/399155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/paulwong/" target="_blank">paulwong</a> 2013-05-11 21:56 <a href="http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Apache MINA 开发高性能¾|‘络应用½E‹åº[转]http://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.htmlpaulwongpaulwongSat, 11 May 2013 13:41:00 GMThttp://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.htmlhttp://www.aygfsteel.com/paulwong/comments/399154.htmlhttp://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.html#Feedback0http://www.aygfsteel.com/paulwong/comments/commentRss/399154.htmlhttp://www.aygfsteel.com/paulwong/services/trackbacks/399154.html Apache MINA(Multipurpose Infrastructure for Network Applications) æ˜?Apache ¾l„织一个较新的™å¹ç›®åQŒå®ƒä¸ºå¼€å‘高性能和高可用性的¾|‘络应用½E‹åºæä¾›äº†éžå¸æ€¾¿åˆ©çš„æ¡†æž¶ã€‚当前发行的 MINA 版本支持åŸÞZºŽ Java NIO 技术的 TCP/UDP 应用½E‹åºå¼€å‘、串口通讯½E‹åºåQˆåªåœ¨æœ€æ–°çš„预览版中提供åQ‰ï¼ŒMINA 所支持的功能也在进一步的扩展中ã€?

目前正在使用 MINA çš„èÊY件包括有åQšApache Directory Project、AsyncWeb、AMQPåQˆAdvanced Message Queuing ProtocolåQ‰ã€RED5 ServeråQˆMacromedia Flash Media RTMPåQ‰ã€ObjectRADIUS、Openfire ½{‰ç­‰ã€?

本文ž®†é€šè¿‡ä¸€ä¸ªç®€å•的问候程åº?HelloServer 来介¾l?MINA 的基¼‹€æž¶æž„的同时演½Cºå¦‚何ä‹É用MINA 开发网¾lœåº”用程序ã€?

环境准备

首先到官方网站下载最新的 MINA 版本åQŒåœ°å€æ˜¯ï¼š(x¨¬)http://mina.apache.org/downloads.html。下载之前先介绍一ä¸?MINA 的两个版本:(x¨¬)1.0.x 适合˜qè¡ŒçŽ¯å¢ƒä¸?JDK1.4åQ?.1.x 适合 JDK1.5 的版本,两者的¾~–译环境都需è¦?JDK1.5。JDK1.5 已经是非常普遍了åQŒæœ¬æ–‡ä¸­ä½¿ç”¨ 1.1.5 版本çš?MINAåQŒç¼–译和˜qè¡Œæ‰€éœ€çš„æ–‡ä»¶æ˜¯ mina-core-1.1.5.jarã€?
下蝲 MINA 的依赖包 slf4j。MINA 使用此项目作为日志信息的输出åQŒè€?MINA 本èínòq¶ä¸é™„带此项目包åQŒè¯·åˆ°http://www.slf4j.org/download.html 地址下蝲 slf4j 包,slf4j ™å¹ç›®è§£åŽ‹åŽæœ‰å¾ˆå¤šçš„æ–‡ä»Óž¼Œæœ¬ä¾‹ä¸­åªéœ€è¦å…¶ä¸­çš„ slf4j-api-1.4.3.jar å’?slf4j-simple-1.4.3.jar ˜q™ä¸¤ä¸?jar æ–‡äšg。如果没有这两个文äšgž®×ƒ¼š(x¨¬)坯D‡´å¯åЍ例子½E‹åºçš„æ—¶å€™æŠ¥ org/slf4j/LoggerFactory ¾cÀL²¡æ‰‘Öˆ°çš„错误ã€?
当然要求机器上必™å»è£…æœ?1.5 或者更新版本的 JDKã€?
最好你应该选择一个顺手的 Java 开发环境例å¦?Eclipse 或è€?NetBeans 之类的,可以更方便的¾~–码和调试,虽然我们的最低要求只是一个简单的文本¾~–辑器而已ã€?



¾~–写代码òq¶æ‰§è¡?

¾~–写代码 HelloServer.java 如下

package demo.mina.echo;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.common.*;
import org.apache.mina.transport.socket.nio.*;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;

/**
 * HelloServer演示½E‹åº
 * 
@author liudong (
                    
http://www.dlog.cn/javayou
                )
 
*/
public class HelloServer {

    private static final int PORT = 8080;
/**
 * 
@param args
 * 
@throws IOException 
 
*/
public static void main(String[] args) throws IOException {
        IoAcceptor acceptor = new SocketAcceptor();        
        IoAcceptorConfig config = new SocketAcceptorConfig();
        DefaultIoFilterChainBuilder chain = config.getFilterChain();
        //使用字符串编ç ?/span>
        chain.addLast("codec", 
new ProtocolCodecFilter(new TextLineCodecFactory()));
        //启动HelloServer
        acceptor.bind(new InetSocketAddress(PORT), new HelloHandler(), config);
        System.out
.println("HelloServer started on port " + 
PORT);
    }
}

/**
 * HelloServer的处理逻辑
 * 
@author liudong
 
*/
class HelloHandler extends IoHandlerAdapter {
/**
 * å½“有异常发生时触å?br />  
*/
@Override
    public void exceptionCaught(IoSession ssn, Throwable cause) {
        cause.printStackTrace();
        ssn.close();
    }

/**
 * æœ‰æ–°˜qžæŽ¥æ—¶è§¦å?br />  
*/
@Override
public void sessionOpened(IoSession ssn) throws Exception {
    System.out.println("session open for " + ssn.getRemoteAddress());
    }

/**
 * ˜qžæŽ¥è¢«å…³é—­æ—¶è§¦å‘
 
*/
@Override
public void sessionClosed(IoSession ssn) throws Exception {
    System.out.println("session closed from " + ssn.getRemoteAddress());
    }

/**
 * æ”¶åˆ°æ¥è‡ªå®¢æˆ·ç«¯çš„æ¶ˆæ¯
 
*/
public void messageReceived(IoSession ssn, Object msg) throws Exception {    
    String ip = ssn.getRemoteAddress().toString();
System.out.println("===> Message From " + ip +" : " + msg);    
    ssn.write("Hello " + msg);
    }
}

¾~–译执行
先不用试着去读懂每一行代码的具体意思,用你™åºæ‰‹çš„编译器¾~–译 HelloServer.javaåQŒå¦‚果报错请¼‹®è®¤æ˜¯å¦å·²å°†å‰é¢æåˆ°çš„三ä¸?jar æ–‡äšgæ·ÕdŠ è‡³ç±»è·¯å¾„ä¸­ã€‚å¦‚æžœä¸€åˆ‡é¡ºåˆ©æŽ¥ç€ž®±å¯ä»¥å¯åЍHelloServer ½E‹åºåQŒå¯åŠ¨åŽæç¤ºåQšHelloServer started on port 8080 表示启动成功åQŒå¦‚果启动失败,问题无外乎是¾cÀL²¡æ‰‘Öˆ°æˆ–者端口占用。如果端口被占用的话åQŒæ¢ä¸€ä¸ªç½—åQŒä¿®æ”?PORT 帔R‡å€¼åŽå†æ¬¡¾~–译òq¶å¯åЍã€?

‹¹‹è¯•服务å™?
打开命ä×o(h¨´)行窗口,输入 telnet localhost 8080 后,输入æ‚(zh¨¨n)¨çš„è‹±æ–‡åæˆ–è€…å…¶ä»–ä¸€äº›äØ•ä¸ƒå…«¾pŸçš„字符后回车再åŽÈœ‹çœ‹åˆšå¯åŠ¨çš„æœåŠ¡ç¨‹åºæœ‰ä½•ååº”ã€‚æˆ‘çš„ååº”å¦‚ä¸‹ï¼š(x¨¬)

HelloServer started on port 8080
session open for /127.0.0.1:3023
===> Message From /127.0.0.1:3023 :hello
===> Message From /127.0.0.1:3023 :hello
===> Message From /127.0.0.1:3023 :liudong
===> Message From /127.0.0.1:3023 :Winter Lau



好了åQŒä¸€åˆ‡æ­£å¸¸ï¼Œæ­å–œä½ çš„½W¬ä¸€ä¸ªä‹Éç”?MINA 开发的¾|‘络½E‹åºå·²ç»æˆåŠŸ˜qè¡Œäº†ã€?




MINA 基本¾cÈš„æè¿°

在介¾læž¶æž„之前先认识几个接口åQ?

IoAccepter 相当于网¾lœåº”用程序中的服务器ç«?

IoConnector 相当于客æˆïL(f¨¥ng)«¯

IoSession 当前客户端到服务器端的一个连接实�

IoHandler 业务处理逻辑

IoFilter ˜q‡æ×o(h¨´)器用于æ?zh¨¨n)¬æŽ¥é€šè®¯å±‚接口与业务层接å?






MINA 的基¼‹€æž¶æž„

下图æ˜?MINA 的架构图åQ?


å›?1åQšMINA 的架构图


在图中的模块链中åQŒIoService 便是应用½E‹åºçš„入口,相当于我们前面代码中çš?IoAccepteråQŒIoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来æ·ÕdŠ å¤šä¸ª IoFilteråQŒè¿™äº?IoFilter ½W¦åˆè´£ä“Qé“¾æ¨¡å¼åÆˆç”?IoProcessor ¾U¿ç¨‹è´Ÿè´£è°ƒç”¨ã€‚è€?IoAccepter åœ?ioService 接口的基¼‹€ä¸Šè¿˜æä¾›¾l‘定某个通讯端口以及取消¾l‘定的接口。在上面的例子中åQŒæˆ‘们是˜q™æ ·ä½¿ç”¨ IoAccepter 的:(x¨¬)

IoAcceptor acceptor = new SocketAcceptor();



相当于我们ä‹É用了 Socket é€šè®¯æ–¹å¼ä½œäØ“(f¨´)服务的接入,当前版本çš?MINA ˜q˜æä¾›äº†é™?SocketAccepter 外的åŸÞZºŽæ•°æ®æŠ¥æ–‡é€šè®¯çš?DatagramAccepter 以及åŸÞZºŽ½Ž¡é“通讯çš?VmPipeAccepter。另外还包括串口通讯接入方式åQŒç›®å‰åŸºäºŽä¸²å£é€šè®¯çš„æŽ¥å…¥æ–¹å¼å·²¾låœ¨æœ€æ–°æµ‹è¯•版çš?MINA 中提供。你也可以自行实çŽ?IoService 接口来ä‹É用自å·Þqš„通讯方式ã€?

而在上图中最右端也就æ˜?IoHandleråQŒè¿™ä¾¿æ˜¯ä¸šåŠ¡å¤„ç†æ¨¡å—ã€‚ç›¸å½“äºŽå‰é¢ä¾‹å­ä¸­çš„ HelloHandler ¾c…R€‚在业务处理¾cÖM¸­ä¸éœ€è¦å޻兛_¿ƒå®žé™…的通讯¾l†èŠ‚åQŒåª½Ž¡å¤„理客æˆïL(f¨¥ng)«¯ä¼ è¾“˜q‡æ¥çš„信息即可。编å†?Handler ¾cÕd°±æ˜¯ä‹Éç”?MINA 开发网¾lœåº”用程序的重心所在,相当äº?MINA 已经帮你处理了所有的通讯斚w¢çš„ç»†èŠ‚é—®é¢˜ã€‚äØ“(f¨´)了简åŒ?Handler ¾c»ï¼ŒMINA 提供äº?IoHandlerAdapter ¾c»ï¼Œæ­¤ç±»ä»…仅是实çŽîCº† IoHandler 接口åQŒä½†òq¶ä¸åšä“Q何处理ã€?

一ä¸?IoHandler 接口中具有如下一些方法(摘自 MINA çš?API 文档åQ‰ï¼š(x¨¬)

void exceptionCaught(IoSession session, Throwable cause)
当接口中其他æ–ÒŽ(gu¨©)³•抛出异常未被捕获时触发此æ–ÒŽ(gu¨©)³•
void messageReceived(IoSession session, Object message)
当接收到客户端的è¯äh±‚信息后触发此æ–ÒŽ(gu¨©)³•.
void messageSent(IoSession session, Object message)
当信息已¾lä¼ é€ç»™å®¢æˆ·ç«¯åŽè§¦å‘此方æ³?
void sessionClosed(IoSession session)
当连接被关闭时触发,例如客户端程序意外退出等½{?
void sessionCreated(IoSession session)
当一个新客户端连接后触发此方�
void sessionIdle(IoSession session, IdleStatus status)
当连接空闲时触发此方�
void sessionOpened(IoSession session)
当连接后打开时触发此æ–ÒŽ(gu¨©)³•åQŒä¸€èˆ¬æ­¤æ–ÒŽ(gu¨©)³•ä¸?sessionCreated ä¼?x¨¬)被同时触å?


前面我们提到 IoService 是负责底层通讯接入åQŒè€?IoHandler 是负责业务处理的。那ä¹?MINA 架构图中çš?IoFilter 作何用途呢åQŸç­”案是你想作何用途都可以。但是有一个用途却是必™åȝš„åQŒé‚£ž®±æ˜¯ä½œäØ“(f¨´) IoService å’?IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceivedåQŒè¿™ä¸ªæ–¹æ³•çš„½W¬äºŒä¸ªå‚数是一ä¸?Object 型的消息åQŒæ€ÀL‰€å‘¨çŸ¥åQŒObject 是所æœ?Java 对象的基¼‹€åQŒé‚£åˆ°åº•谁来军_®š˜q™ä¸ªæ¶ˆæ¯åˆ°åº•是什么类型呢åQŸç­”案也ž®±åœ¨˜q™ä¸ª IoFilter 中。在前面使用的例子中åQŒæˆ‘们添加了一ä¸?IoFilter æ˜?new ProtocolCodecFilter(new TextLineCodecFactory())åQŒè¿™ä¸ªè¿‡æ»¤å™¨çš„作用是ž®†æ¥è‡ªå®¢æˆïL(f¨¥ng)«¯è¾“入的信息è{换成一行行的文本后传递给 IoHandleråQŒå› æ­¤æˆ‘们可以在 messageReceived 中直接将 msg 对象强制转换æˆ?String 对象ã€?

而如果我们不提供ä»ÖM½•˜q‡æ×o(h¨´)器的话,那么åœ?messageReceived æ–ÒŽ(gu¨©)³•中的½W¬äºŒä¸ªå‚数类型就是一ä¸?byte 的缓冲区åQŒå¯¹åº”çš„¾cÀL˜¯ org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放åœ?IoHandler 中来做,但这òq¶ä¸æ˜¯æŽ¨èçš„做法åQŒä‹É原来清晰的模型又模糊èµäh¥åQŒå˜å¾?IoHandler 不只是业务处理,˜q˜å¾—充当协议解析的ä“Q务ã€?

MINA自èín带有一些常用的˜q‡æ×o(h¨´)器,例如LoggingFilteråQˆæ—¥å¿—记录)、BlackListFilteråQˆé»‘名单˜q‡æ×o(h¨´)åQ‰ã€CompressionFilteråQˆåŽ‹¾~©ï¼‰ã€SSLFilteråQˆSSL加密åQ‰ç­‰ã€?



å…¶ä»–

MINA 不仅仅是用来开发网¾lœæœåŠ¡å™¨ç«¯åº”ç”¨ç¨‹åºï¼Œå®ƒä¸€æ ·å¯ä»¥ä‹Éç”?IoConnector 来连接到各种各样的网¾lœæœåŠ¡ç¨‹åºã€?

通过本文ä¸?HelloServer ˜q™ä¸ªä¾‹å­åQŒæˆ‘们在惊叹 MINA 可以带来多么大便利的同时åQŒè¿˜ä¸å¾—ä¸äØ“(f¨´)其卓­‘Šçš„æ€§èƒ½è€Œéª„å‚ÔŒ¼Œæ®ç§°ä½¿ç”¨MINA开发服务器½E‹åºçš„æ€§èƒ½å·²ç»é€ÆD¿‘使用 C/C++ 语言开发的¾|‘络服务。作ä¸?MINA 的入门文章,性能问题不在本文讨论范围内ã€?

另外åœ?MINA 压羃包中附带有不ž®‘比 HelloServer 要好得多的例子,通过˜q™äº›ä¾‹å­å¯ä»¥˜q›ä¸€æ­¥çš„了解òq¶æŽŒæ?MINAã€?




参考资�

http://mina.apache.org MINA 官方¾|‘ç«™


http://mina.apache.org/features.html æ‚(zh¨¨n)¨å¯ä»¥åœ¨˜q™é‡ŒæŸ¥çœ‹å…³äºŽ MINA 的更多特æ€?


http://mina.apache.org/testimonials.html 看看别äh是如何评ä»?MINA çš?http://asyncweb.safehaus.org/使用 MINA 开发的高性能 WEB 服务å™?nbsp;


]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ºÍÌïÏØ| Ä˶«ÏØ| ÎåÕ¯ÏØ| ÌÁ¹ÁÇø| ×ÊÐËÊÐ| °¢ÀÕÌ©ÊÐ| ÅÍʯÊÐ| ¹¤²¼½­´ïÏØ| ¸ÊÈªÏØ| ÀäË®½­ÊÐ| ÑÀ¿ËʯÊÐ| аͶû»¢ÓÒÆì| ÖÓÏéÊÐ| ¶î¶û¹ÅÄÉÊÐ| ´óÖñÏØ| ÎĵÇÊÐ| Ì©Ë³ÏØ| ÈÄÆ½ÏØ| °Í¶«ÏØ| ³µéÏØ| ÒÀ°²ÏØ| ¾¸±ßÏØ| ÐÇ×ù| µÂÇåÏØ| ãå´¨ÏØ| ²ÔÏªÏØ| ´óÖñÏØ| ÇɼÒÏØ| ÐÏÌ¨ÏØ| ººÖÐÊÐ| ¾ÅÁú³ÇÇø| ̨ÄÏÏØ| ÃáÄþÏØ| Ë«Á÷ÏØ| ÐÂÏçÏØ| ÁÖµéÏØ| ÓͼâÍúÇø| ÎÌÔ´ÏØ| ¶«·áÏØ| ÍþÔ¶ÏØ| ÇØ»ÊµºÊÐ|