﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-paulwong-随笔分类-MINA</title><link>http://www.blogjava.net/paulwong/category/53575.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 14 May 2013 17:15:45 GMT</lastBuildDate><pubDate>Tue, 14 May 2013 17:15:45 GMT</pubDate><ttl>60</ttl><item><title>MINA资源</title><link>http://www.blogjava.net/paulwong/archive/2013/05/14/399270.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Tue, 14 May 2013 09:41:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2013/05/14/399270.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/399270.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2013/05/14/399270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/399270.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/399270.html</trackback:ping><description><![CDATA[socket 通信<br />
<a href="http://yaojialing.iteye.com/category/115609" target="_blank">
http://yaojialing.iteye.com/category/115609<br />
</a>
<br />
使用 Apache MINA 2 开发网络应用<br /><a href="http://www.ibm.com/developerworks/cn/java/j-lo-mina2/" target="_blank">http://www.ibm.com/developerworks/cn/java/j-lo-mina2/</a><br /><br />直接操作mina的IoBuffer流 <br /><a href="http://autumnice.blog.163.com/blog/static/555200201011493410310/" target="_blank">http://autumnice.blog.163.com/blog/static/555200201011493410310/</a><br /><br />pache mina 学习（十一）-----状态机（stateMachine）<br /><a href="http://cages.iteye.com/blog/1530849" target="_blank">http://cages.iteye.com/blog/1530849</a><br /><br />运用 Apache MINA 2 开发网络运用 [多图]<br /><a href="http://www.lj8lj8.com/chengxukaifa/Java/338853_13.html" target="_blank">http://www.lj8lj8.com/chengxukaifa/Java/338853_13.html</a><br /><br /><br /><img src ="http://www.blogjava.net/paulwong/aggbug/399270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2013-05-14 17:41 <a href="http://www.blogjava.net/paulwong/archive/2013/05/14/399270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Apache Mina实现的TCP长连接和短连接实例</title><link>http://www.blogjava.net/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.blogjava.net/paulwong/archive/2013/05/11/399155.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/399155.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2013/05/11/399155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/399155.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/399155.html</trackback:ping><description><![CDATA[1、前言<br />
<br />
Apache MINA是Apache组织的一个优秀的项目。MINA是Multipurpose Infrastructure for NetworkApplications的缩写。它是一个网络应用程序框架，用来帮助用户非常方便地开发高性能和高可靠性的网络应用程序。在本文中介绍了 如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用。<br />
<br />
2、系统介绍<br />
<br />
2.1系统框架<br />
<br />
整个系统由两个服务端程序和两个客户端程序组成。分别实现TCP长连接和短连接通信。<br />
<br />
系统业务逻辑是一个客户端与服务端建立长连接，一个客户端与服务端建立短连接。数据从短连接客户端经过服务端发送到长连接客户端，并从长连接客户端接收响应数据。当收到响应数据后断开连接。<br />
<br />
系统架构图如下：<br />
<br />
<br />
2.2处理流程<br />
<br />
系统处理流程如下：<br />
<br />
1）       启动服务端程序，监听8001和8002端口。<br />
<br />
2）       长连接客户端向服务端8002端口建立连接，服务端将连接对象保存到共享内存中。由于采用长连接方式，连接对象是唯一的。<br />
<br />
3）       短连接客户端向服务端8001端口建立连接。建立连接后创建一个连接对象。<br />
<br />
4）       短连接客户端连接成功后发送数据。服务端接收到数据后从共享内存中得到长连接方式的连接对象，使用此对象向长连接客户端发送数据。发送前将短连接对象设为长连接对象的属性值。<br />
<br />
5）       长连接客户端接收到数据后返回响应数据。服务端从长连接对象的属性中取得短连接对象，通过此对象将响应数据发送给短连接客户端。<br />
<br />
6）       短连接客户端收到响应数据后，关闭连接。<br />
<br />
3、服务端程序<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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaLongConnServer&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;PORT&nbsp;=&nbsp;8002;<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;start()<span style="color: #0000FF; ">throws</span>&nbsp;IOException{<br />
<br />
IoAcceptor&nbsp;acceptor&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketAcceptor();<br />
<br />
<br />
<br />
acceptor.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />
<br />
acceptor.getFilterChain().addLast("codec",&nbsp;newProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));<br />
<br />
<br />
<br />
acceptor.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;MinaLongConnServerHandler());<br />
<br />
acceptor.getSessionConfig().setReadBufferSize(2048);<br />
<br />
acceptor.bind(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(PORT));<br />
<br />
System.out.println("Listeningon&nbsp;port&nbsp;"&nbsp;+&nbsp;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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaLongConnServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;(Logger)&nbsp;LoggerFactory.getLogger(getClass());<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionOpened(IoSession&nbsp;session)&nbsp;{<br />
<br />
InetSocketAddress&nbsp;remoteAddress&nbsp;=&nbsp;(InetSocketAddress)session.getRemoteAddress();<br />
<br />
String&nbsp;clientIp&nbsp;=&nbsp;remoteAddress.getAddress().getHostAddress();<br />
<br />
logger.info("LongConnect&nbsp;Server&nbsp;opened&nbsp;Session&nbsp;ID&nbsp;="+String.valueOf(session.getId()));<br />
<br />
logger.info("接收来自客户端&nbsp;:"&nbsp;+&nbsp;clientIp&nbsp;+&nbsp;"的连接.");<br />
<br />
Initialization&nbsp;init&nbsp;=&nbsp;Initialization.getInstance();<br />
<br />
HashMap&lt;String,&nbsp;IoSession&gt;&nbsp;clientMap&nbsp;=init.getClientMap();<br />
<br />
clientMap.put(clientIp,&nbsp;session);<br />
<br />
}<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;session,&nbsp;Object&nbsp;message)&nbsp;{<br />
<br />
logger.info("Messagereceived&nbsp;in&nbsp;the&nbsp;long&nbsp;connect&nbsp;server..");<br />
<br />
String&nbsp;expression&nbsp;=&nbsp;message.toString();<br />
<br />
logger.info("Message&nbsp;is:"&nbsp;+&nbsp;expression);<br />
<br />
IoSession&nbsp;shortConnSession&nbsp;=(IoSession)&nbsp;session.getAttribute("shortConnSession");<br />
<br />
logger.info("ShortConnect&nbsp;Server&nbsp;Session&nbsp;ID&nbsp;="+String.valueOf(shortConnSession.getId()));<br />
<br />
shortConnSession.write(expression);<br />
<br />
}<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionIdle(IoSession&nbsp;session,&nbsp;IdleStatus&nbsp;status)&nbsp;{<br />
<br />
logger.info("Disconnectingthe&nbsp;idle.");<br />
<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;disconnect&nbsp;an&nbsp;idle&nbsp;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>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(IoSession&nbsp;session,&nbsp;Throwable&nbsp;cause)&nbsp;{<br />
<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;close&nbsp;the&nbsp;connection&nbsp;onexceptional&nbsp;situation</span><span style="color: #008000; "><br />
</span><br />
logger.warn(cause.getMessage(),&nbsp;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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaShortConnServer&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;PORT&nbsp;=&nbsp;8001;<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;start()<span style="color: #0000FF; ">throws</span>&nbsp;IOException{<br />
<br />
IoAcceptor&nbsp;acceptor&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketAcceptor();<br />
<br />
<br />
<br />
acceptor.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />
<br />
acceptor.getFilterChain().addLast("codec",&nbsp;newProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));<br />
<br />
<br />
<br />
acceptor.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;MinaShortConnServerHandler());<br />
<br />
acceptor.getSessionConfig().setReadBufferSize(2048);<br />
<br />
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,&nbsp;3);<br />
<br />
acceptor.bind(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(PORT));<br />
<br />
System.out.println("Listeningon&nbsp;port&nbsp;"&nbsp;+&nbsp;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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaShortConnServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;(Logger)&nbsp;LoggerFactory.getLogger(getClass());<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionOpened(IoSession&nbsp;session)&nbsp;{<br />
<br />
InetSocketAddress&nbsp;remoteAddress&nbsp;=&nbsp;(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>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;session,&nbsp;Object&nbsp;message)&nbsp;{<br />
<br />
logger.info("Messagereceived&nbsp;in&nbsp;the&nbsp;short&nbsp;connect&nbsp;server<img src="http://www.blogjava.net/Images/dot.gif" alt="" />");<br />
<br />
String&nbsp;expression&nbsp;=&nbsp;message.toString();<br />
<br />
Initialization&nbsp;init&nbsp;=&nbsp;Initialization.getInstance();<br />
<br />
HashMap&lt;String,&nbsp;IoSession&gt;&nbsp;clientMap&nbsp;=init.getClientMap();<br />
<br />
<span style="color: #0000FF; ">if</span>&nbsp;(clientMap&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>&nbsp;||&nbsp;clientMap.size()&nbsp;==&nbsp;0)&nbsp;{<br />
<br />
session.write("error");<br />
<br />
}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />
<br />
IoSession&nbsp;longConnSession&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />
<br />
Iterator&lt;String&gt;&nbsp;iterator&nbsp;=clientMap.keySet().iterator();<br />
<br />
String&nbsp;key&nbsp;=&nbsp;"";<br />
<br />
<span style="color: #0000FF; ">while</span>&nbsp;(iterator.hasNext())&nbsp;{<br />
<br />
key&nbsp;=&nbsp;iterator.next();<br />
<br />
longConnSession&nbsp;=&nbsp;clientMap.get(key);<br />
<br />
}<br />
<br />
logger.info("ShortConnect&nbsp;Server&nbsp;Session&nbsp;ID&nbsp;:"+String.valueOf(session.getId()));<br />
<br />
logger.info("LongConnect&nbsp;Server&nbsp;Session&nbsp;ID&nbsp;:"+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>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionIdle(IoSession&nbsp;session,&nbsp;IdleStatus&nbsp;status)&nbsp;{<br />
<br />
logger.info("Disconnectingthe&nbsp;idle.");<br />
<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;disconnect&nbsp;an&nbsp;idle&nbsp;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>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(IoSession&nbsp;session,&nbsp;Throwable&nbsp;cause)&nbsp;{<br />
<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;close&nbsp;the&nbsp;connection&nbsp;onexceptional&nbsp;situation</span><span style="color: #008000; "><br />
</span><br />
logger.warn(cause.getMessage(),&nbsp;cause);<br />
<br />
session.close(<span style="color: #0000FF; ">true</span>);<br />
<br />
}<br />
<br />
}</div>
<br />
<br />
<br />
4、客户端程序<br />
<br />
4.1长连接客户端<br />
<br />
使用java.net.Socket来实现向服务端建立连接。Socket建立后一直保持连接，从服务端接收到数据包后直接将原文返回。<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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;TcpKeepAliveClient&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;String&nbsp;ip;<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port;<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;Socket&nbsp;socket&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;timeout&nbsp;=&nbsp;50&nbsp;*&nbsp;1000;<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;TcpKeepAliveClient(String&nbsp;ip,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port)&nbsp;{<br />
<br />
<span style="color: #0000FF; ">this</span>.ip&nbsp;=&nbsp;ip;<br />
<br />
<span style="color: #0000FF; ">this</span>.port&nbsp;=&nbsp;port;<br />
<br />
}<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;receiveAndSend()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException&nbsp;{<br />
<br />
InputStream&nbsp;input&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />
<br />
OutputStream&nbsp;output&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">try</span>&nbsp;{<br />
<br />
<span style="color: #0000FF; ">if</span>&nbsp;(socket&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>&nbsp;||&nbsp;socket.isClosed()&nbsp;||&nbsp;!socket.isConnected())&nbsp;{<br />
<br />
socket&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Socket();<br />
<br />
InetSocketAddress&nbsp;addr&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(ip,&nbsp;port);<br />
<br />
socket.connect(addr,&nbsp;timeout);<br />
<br />
socket.setSoTimeout(timeout);<br />
<br />
System.out.println("TcpKeepAliveClientnew&nbsp;");<br />
<br />
}<br />
<br />
<br />
<br />
input&nbsp;=&nbsp;socket.getInputStream();<br />
<br />
output&nbsp;=&nbsp;socket.getOutputStream();<br />
<br />
<br />
<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;read&nbsp;body</span><span style="color: #008000; "><br />
</span><br />
<span style="color: #0000FF; ">byte</span>[]&nbsp;receiveBytes&nbsp;=&nbsp;{};<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;收到的包字节数组</span><span style="color: #008000; "><br />
</span><br />
<span style="color: #0000FF; ">while</span>&nbsp;(<span style="color: #0000FF; ">true</span>)&nbsp;{<br />
<br />
<span style="color: #0000FF; ">if</span>&nbsp;(input.available()&nbsp;&gt;&nbsp;0)&nbsp;{<br />
<br />
receiveBytes&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<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; ">&nbsp;send</span><span style="color: #008000; "><br />
</span><br />
System.out.println("TcpKeepAliveClientsend&nbsp;date&nbsp;:"&nbsp;+&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;String(receiveBytes));<br />
<br />
output.write(receiveBytes,&nbsp;0,&nbsp;receiveBytes.length);<br />
<br />
output.flush();<br />
<br />
}<br />
<br />
}<br />
<br />
<br />
<br />
}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(Exception&nbsp;e)&nbsp;{<br />
<br />
e.printStackTrace();<br />
<br />
System.out.println("TcpClientnew&nbsp;socket&nbsp;error");<br />
<br />
}<br />
<br />
}<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />
<br />
TcpKeepAliveClient&nbsp;client&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;TcpKeepAliveClient("127.0.0.1",&nbsp;8002);<br />
<br />
client.receiveAndSend();<br />
<br />
}<br />
<br />
<br />
<br />
}</div>
<br />
4.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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaShortClient&nbsp;{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;PORT&nbsp;=&nbsp;8001;<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException,InterruptedException&nbsp;{<br />
<br />
IoConnector&nbsp;connector&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketConnector();<br />
<br />
connector.getSessionConfig().setReadBufferSize(2048);<br />
<br />
<br />
<br />
connector.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />
<br />
connector.getFilterChain().addLast("codec",&nbsp;newProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));<br />
<br />
<br />
<br />
connector.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;MinaShortClientHandler());<br />
<br />
<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;=&nbsp;10;&nbsp;i++)&nbsp;{<br />
<br />
ConnectFuture&nbsp;future&nbsp;=&nbsp;connector.connect(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress("127.0.0.1",&nbsp;PORT));<br />
<br />
future.awaitUninterruptibly();<br />
<br />
IoSession&nbsp;session&nbsp;=future.getSession();<br />
<br />
session.write(i);<br />
<br />
session.getCloseFuture().awaitUninterruptibly();<br />
<br />
<br />
<br />
System.out.println("result="&nbsp;+&nbsp;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>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MinaShortClientHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter{<br />
<br />
<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;(Logger)&nbsp;LoggerFactory.getLogger(getClass());<br />
<br />
<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;MinaShortClientHandler()&nbsp;{<br />
<br />
<br />
<br />
}<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionOpened(IoSession&nbsp;session)&nbsp;{<br />
<br />
}<br />
<br />
<br />
<br />
@Override<br />
<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;session,&nbsp;Object&nbsp;message)&nbsp;{<br />
<br />
logger.info("Messagereceived&nbsp;in&nbsp;the&nbsp;client..");<br />
<br />
logger.info("Message&nbsp;is:"&nbsp;+&nbsp;message.toString());<br />
<br />
session.setAttribute("result",&nbsp;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>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(IoSession&nbsp;session,&nbsp;Throwable&nbsp;cause)&nbsp;{<br />
<br />
session.close(<span style="color: #0000FF; ">true</span>);<br />
<br />
}<br />
<br />
}</div>
<br />
5、总结<br />
<br />
通过本文中的例子，Apache Mina在服务端可实现TCP协议长连接和短连接。在客户端只实现了短连接模式，长连接模式也是可以实现的（在本文中还是采用传统的java Socket方式）。两个服务端之间通过共享内存的方式来传递连接对象也许有更好的实现方式。<img src ="http://www.blogjava.net/paulwong/aggbug/399155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2013-05-11 21:56 <a href="http://www.blogjava.net/paulwong/archive/2013/05/11/399155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Apache MINA 开发高性能网络应用程序[转]</title><link>http://www.blogjava.net/paulwong/archive/2013/05/11/399154.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Sat, 11 May 2013 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/paulwong/archive/2013/05/11/399154.html</guid><wfw:comment>http://www.blogjava.net/paulwong/comments/399154.html</wfw:comment><comments>http://www.blogjava.net/paulwong/archive/2013/05/11/399154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/paulwong/comments/commentRss/399154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/paulwong/services/trackbacks/399154.html</trackback:ping><description><![CDATA[本文将通过一个简单的问候程序 HelloServer 来介绍 MINA 的基础架构的同时演示如何使用 MINA 开发网络应用程序。 <br />
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目，它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序（只在最新的预览版中提供），MINA 所支持的功能也在进一步的扩展中。 <br />
<br />
目前正在使用 MINA 的软件包括有：Apache Directory Project、AsyncWeb、AMQP（Advanced Message Queuing Protocol）、RED5 Server（Macromedia Flash Media RTMP）、ObjectRADIUS、Openfire 等等。 <br />
<br />
本文将通过一个简单的问候程序 HelloServer 来介绍 MINA 的基础架构的同时演示如何使用MINA 开发网络应用程序。 <br />
<br />
环境准备 <br />
<br />
首先到官方网站下载最新的 MINA 版本，地址是：http://mina.apache.org/downloads.html。下载之前先介绍一下 MINA 的两个版本：1.0.x 适合运行环境为 JDK1.4，1.1.x 适合 JDK1.5 的版本，两者的编译环境都需要 JDK1.5。JDK1.5 已经是非常普遍了，本文中使用 1.1.5 版本的 MINA，编译和运行所需的文件是 mina-core-1.1.5.jar。 <br />
下载 MINA 的依赖包 slf4j。MINA 使用此项目作为日志信息的输出，而 MINA 本身并不附带此项目包，请到http://www.slf4j.org/download.html 地址下载 slf4j 包，slf4j 项目解压后有很多的文件，本例中只需要其中的 slf4j-api-1.4.3.jar 和 slf4j-simple-1.4.3.jar 这两个 jar 文件。如果没有这两个文件就会导致启动例子程序的时候报 org/slf4j/LoggerFactory 类没找到的错误。 <br />
当然要求机器上必须装有 1.5 或者更新版本的 JDK。 <br />
最好你应该选择一个顺手的 Java 开发环境例如 Eclipse 或者 NetBeans 之类的，可以更方便的编码和调试，虽然我们的最低要求只是一个简单的文本编辑器而已。 <br />
<br />
<br />
<br />
编写代码并执行 <br />
<br />
编写代码 HelloServer.java 如下
<div><br />
</div>
<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; ">package</span>&nbsp;demo.mina.echo;<br />
<br />
<span style="color: #0000FF; ">import</span>&nbsp;java.io.IOException;<br />
<span style="color: #0000FF; ">import</span>&nbsp;java.net.InetSocketAddress;<br />
<br />
<span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.common.*;<br />
<span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.transport.socket.nio.*;<br />
<span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.ProtocolCodecFilter;<br />
<span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.textline.TextLineCodecFactory;<br />
<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;HelloServer演示程序<br />
&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;liudong&nbsp;(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; text-decoration: underline; ">http://www.dlog.cn/javayou</span><span style="color: #008000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloServer&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;PORT&nbsp;=&nbsp;8080;<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;</span><span style="color: #808080; ">@param</span><span style="color: #008000; ">&nbsp;args<br />
&nbsp;*&nbsp;</span><span style="color: #808080; ">@throws</span><span style="color: #008000; ">&nbsp;IOException&nbsp;<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IoAcceptor&nbsp;acceptor&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;SocketAcceptor();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IoAcceptorConfig&nbsp;config&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;SocketAcceptorConfig();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultIoFilterChainBuilder&nbsp;chain&nbsp;=&nbsp;config.getFilterChain();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">使用字符串编码</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.addLast("codec",&nbsp;<br />
<span style="color: #0000FF; ">new</span>&nbsp;ProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory()));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">启动HelloServer</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.bind(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(PORT),&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;HelloHandler(),&nbsp;config);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out<br />
.println("HelloServer&nbsp;started&nbsp;on&nbsp;port&nbsp;"&nbsp;+&nbsp;<br />
PORT);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;HelloServer的处理逻辑<br />
&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;liudong<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
<span style="color: #0000FF; ">class</span>&nbsp;HelloHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter&nbsp;{<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;当有异常发生时触发<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(IoSession&nbsp;ssn,&nbsp;Throwable&nbsp;cause)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cause.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;有新连接时触发<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
@Override<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionOpened(IoSession&nbsp;ssn)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("session&nbsp;open&nbsp;for&nbsp;"&nbsp;+&nbsp;ssn.getRemoteAddress());<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;连接被关闭时触发<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
@Override<br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionClosed(IoSession&nbsp;ssn)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("session&nbsp;closed&nbsp;from&nbsp;"&nbsp;+&nbsp;ssn.getRemoteAddress());<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />
&nbsp;*&nbsp;收到来自客户端的消息<br />
&nbsp;</span><span style="color: #008000; ">*/</span><br />
<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;ssn,&nbsp;Object&nbsp;msg)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ip&nbsp;=&nbsp;ssn.getRemoteAddress().toString();<br />
System.out.println("===&gt;&nbsp;Message&nbsp;From&nbsp;"&nbsp;+&nbsp;ip&nbsp;+"&nbsp;:&nbsp;"&nbsp;+&nbsp;msg);&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ssn.write("Hello&nbsp;"&nbsp;+&nbsp;msg);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}
</div>
<div><br />
</div>
<div>编译执行 <br />
先不用试着去读懂每一行代码的具体意思，用你顺手的编译器编译 HelloServer.java，如果报错请确认是否已将前面提到的三个 jar 文件添加至类路径中。如果一切顺利接着就可以启动HelloServer 程序，启动后提示：HelloServer started on port 8080 表示启动成功，如果启动失败，问题无外乎是类没找到或者端口占用。如果端口被占用的话，换一个罗，修改 PORT 常量值后再次编译并启动。 <br />
<br />
测试服务器 <br />
打开命令行窗口，输入 telnet localhost 8080 后，输入您的英文名或者其他一些乱七八糟的字符后回车再去看看刚启动的服务程序有何反应。我的反应如下： <br />
<br />
HelloServer started on port 8080 <br />
session open for /127.0.0.1:3023 <br />
===&gt; Message From /127.0.0.1:3023 :hello <br />
===&gt; Message From /127.0.0.1:3023 :hello <br />
===&gt; Message From /127.0.0.1:3023 :liudong <br />
===&gt; Message From /127.0.0.1:3023 :Winter Lau <br />
<br />
<br />
<br />
好了，一切正常，恭喜你的第一个使用 MINA 开发的网络程序已经成功运行了。 <br />
<br />
<br />
<br />
<br />
MINA 基本类的描述 <br />
<br />
在介绍架构之前先认识几个接口： <br />
<br />
IoAccepter 相当于网络应用程序中的服务器端 <br />
<br />
IoConnector 相当于客户端 <br />
<br />
IoSession 当前客户端到服务器端的一个连接实例 <br />
<br />
IoHandler 业务处理逻辑 <br />
<br />
IoFilter 过滤器用于悬接通讯层接口与业务层接口 <br />
<br />
<br />
<br />
<br />
<br />
<br />
MINA 的基础架构 <br />
<br />
下图是 MINA 的架构图， <br />
<br />
<br />
图 1：MINA 的架构图 <br />
<br />
<img src="http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/image001.jpg" width="500" height="235" alt="" /></div>
<div><br />
在图中的模块链中，IoService 便是应用程序的入口，相当于我们前面代码中的 IoAccepter，IoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来添加多个 IoFilter，这些 IoFilter 符合责任链模式并由 IoProcessor 线程负责调用。而 IoAccepter 在 ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。在上面的例子中，我们是这样使用 IoAccepter 的： <br />
<br />
IoAcceptor acceptor = new SocketAcceptor(); <br />
<br />
<br />
<br />
相当于我们使用了 Socket 通讯方式作为服务的接入，当前版本的 MINA 还提供了除 SocketAccepter 外的基于数据报文通讯的 DatagramAccepter 以及基于管道通讯的 VmPipeAccepter。另外还包括串口通讯接入方式，目前基于串口通讯的接入方式已经在最新测试版的 MINA 中提供。你也可以自行实现 IoService 接口来使用自己的通讯方式。 <br />
<br />
而在上图中最右端也就是 IoHandler，这便是业务处理模块。相当于前面例子中的 HelloHandler 类。在业务处理类中不需要去关心实际的通讯细节，只管处理客户端传输过来的信息即可。编写 Handler 类就是使用 MINA 开发网络应用程序的重心所在，相当于 MINA 已经帮你处理了所有的通讯方面的细节问题。为了简化 Handler 类，MINA 提供了 IoHandlerAdapter 类，此类仅仅是实现了 IoHandler 接口，但并不做任何处理。 <br />
<br />
一个 IoHandler 接口中具有如下一些方法（摘自 MINA 的 API 文档）： <br />
<br />
void exceptionCaught(IoSession session, Throwable cause) <br />
当接口中其他方法抛出异常未被捕获时触发此方法 <br />
void messageReceived(IoSession session, Object message) <br />
当接收到客户端的请求信息后触发此方法. <br />
void messageSent(IoSession session, Object message) <br />
当信息已经传送给客户端后触发此方法. <br />
void sessionClosed(IoSession session) <br />
当连接被关闭时触发，例如客户端程序意外退出等等. <br />
void sessionCreated(IoSession session) <br />
当一个新客户端连接后触发此方法. <br />
void sessionIdle(IoSession session, IdleStatus status) <br />
当连接空闲时触发此方法. <br />
void sessionOpened(IoSession session) <br />
当连接后打开时触发此方法，一般此方法与 sessionCreated 会被同时触发 <br />
<br />
<br />
前面我们提到 IoService 是负责底层通讯接入，而 IoHandler 是负责业务处理的。那么 MINA 架构图中的 IoFilter 作何用途呢？答案是你想作何用途都可以。但是有一个用途却是必须的，那就是作为 IoService 和 IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceived，这个方法的第二个参数是一个 Object 型的消息，总所周知，Object 是所有 Java 对象的基础，那到底谁来决定这个消息到底是什么类型呢？答案也就在这个 IoFilter 中。在前面使用的例子中，我们添加了一个 IoFilter 是 new ProtocolCodecFilter(new TextLineCodecFactory())，这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给 IoHandler，因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。 <br />
<br />
而如果我们不提供任何过滤器的话，那么在 messageReceived 方法中的第二个参数类型就是一个 byte 的缓冲区，对应的类是 org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放在 IoHandler 中来做，但这并不是推荐的做法，使原来清晰的模型又模糊起来，变得 IoHandler 不只是业务处理，还得充当协议解析的任务。 <br />
<br />
MINA自身带有一些常用的过滤器，例如LoggingFilter（日志记录）、BlackListFilter（黑名单过滤）、CompressionFilter（压缩）、SSLFilter（SSL加密）等。 <br />
<br />
<br />
<br />
其他 <br />
<br />
MINA 不仅仅是用来开发网络服务器端应用程序，它一样可以使用 IoConnector 来连接到各种各样的网络服务程序。 <br />
<br />
通过本文中 HelloServer 这个例子，我们在惊叹 MINA 可以带来多么大便利的同时，还不得不为其卓越的性能而骄傲，据称使用MINA开发服务器程序的性能已经逼近使用 C/C++ 语言开发的网络服务。作为 MINA 的入门文章，性能问题不在本文讨论范围内。 <br />
<br />
另外在 MINA 压缩包中附带有不少比 HelloServer 要好得多的例子，通过这些例子可以进一步的了解并掌握 MINA。 <br />
<br />
<br />
<br />
<br />
参考资料 <br />
<br />
http://mina.apache.org MINA 官方网站 <br />
<br />
<br />
http://mina.apache.org/features.html 您可以在这里查看关于 MINA 的更多特性 <br />
<br />
<br />
http://mina.apache.org/testimonials.html 看看别人是如何评价 MINA 的 http://asyncweb.safehaus.org/使用 MINA 开发的高性能 WEB 服务器&nbsp;</div>
<img src ="http://www.blogjava.net/paulwong/aggbug/399154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/paulwong/" target="_blank">paulwong</a> 2013-05-11 21:41 <a href="http://www.blogjava.net/paulwong/archive/2013/05/11/399154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>