Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便
apache mina
利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中。
需要导入的包:
log4j.jar
mina-core-2.0.4.jar
slf4j-api-1.6.3.jar
slf4j-log4j12-1.6.3.jar
服务端代码:
- /**
- * @author aniyo
- * blog: http://aniyo.iteye.com
- */
- public class MinaTimeServer {
- // 服务器监听端口
- private static final int PORT = 8888;
- /**
- *
- */
- public MinaTimeServer() {
- // TODO Auto-generated constructor stub
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- // 服务器端的主要对象
- IoAcceptor acceptor = new NioSocketAcceptor();
- // 设置Filter链
- acceptor.getFilterChain().addLast("logger", new LoggingFilter());
- // 协议解析,采用mina现成的UTF-8字符串处理方式
- acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
- // 设置消息处理类(创建、关闭Session,可读可写等等,继承自接口IoHandler)
- acceptor.setHandler(new TimeServerHandler() );
- // 设置接收缓存区大小
- acceptor.getSessionConfig().setReadBufferSize(2048);
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
- try {
- // 服务器开始监听
- acceptor.bind( new InetSocketAddress(PORT) );
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
服务端业务处理类:
- package aniyo.mina.server;
- import java.util.Date;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IoSession;
- /**
- * @author aniyo
- * blog: http://aniyo.iteye.com
- * 继承自IoHandlerAdapter,IoHandlerAdapter继承接口 IoHandler
- 类IoHandlerAdapter实现了IoHandler的所有方法,只要重载关心的几个方法就可以了
- */
- public class TimeServerHandler extends IoHandlerAdapter {
- @Override
- public void exceptionCaught(IoSession session, Throwable cause)
- throws Exception {
- cause.printStackTrace();
- }
- /*
- * 这个方法是目前这个类里最主要的,
- * 当接收到消息,只要不是quit,就把服务器当前的时间返回给客户端
- * 如果是quit,则关闭客户端连接*/
- @Override
- public void messageReceived(IoSession session, Object message)
- throws Exception {
- String str = message.toString();
- if (str.trim().equalsIgnoreCase("quit")) {
- session.close();
- return;
- }
- Date date = new Date();
- System.out.println("hello"+str+session.getRemoteAddress()+date.toString());
- session.write("i am recived");
- System.out.println("Message written...");
- }
- @Override
- public void sessionClosed(IoSession session) throws Exception {
- // TODO Auto-generated method stub
- super.sessionClosed(session);
- System.out.println("客户端与服务端断开连接.....");
- }
- }
客户端:
- package aniyo.mina.server;
- import java.net.InetSocketAddress;
- import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
- import org.apache.mina.core.future.ConnectFuture;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
- import org.apache.mina.transport.socket.nio.NioSocketConnector;
- /**
- * mina客户端
- * @author aniyo
- * blog:http://aniyo.iteye.com
- */
- public class MinaClient {
- public static void main(String []args)throws Exception{
- //Create TCP/IP connection
- NioSocketConnector connector = new NioSocketConnector();
- //创建接受数据的过滤器
- DefaultIoFilterChainBuilder chain = connector.getFilterChain();
- //设定这个过滤器将一行一行(/r/n)的读取数据
- chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));
- //客户端的消息处理器:一个SamplMinaServerHander对象
- connector.setHandler(new MinaClientHandler());
- //set connect timeout
- connector.setConnectTimeout(30);
- //连接到服务器:
- ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",8888));
- //Wait for the connection attempt to be finished.
- cf.awaitUninterruptibly();
- cf.getSession().getCloseFuture().awaitUninterruptibly();
- connector.dispose();
- }
- }
客户端业务逻辑处理类:
- package aniyo.mina.server;
- import org.apache.mina.core.service.IoHandlerAdapter;
- import org.apache.mina.core.session.IoSession;
- /**
- * 客户端业务处理逻辑
- *
- * @author aniyo blog: http://aniyo.iteye.com
- */
- public class MinaClientHandler extends IoHandlerAdapter {
- // 当客户端连接进入时
- @Override
- public void sessionOpened(IoSession session) throws Exception {
- System.out.println("incomming 客户端: " + session.getRemoteAddress());
- session.write("i am coming");
- }
- @Override
- public void exceptionCaught(IoSession session, Throwable cause)
- throws Exception {
- System.out.println("客户端发送信息异常....");
- }
- // 当客户端发送消息到达时
- @Override
- public void messageReceived(IoSession session, Object message)
- throws Exception {
- System.out.println("服务器返回的数据:" + message.toString());
- }
- @Override
- public void sessionClosed(IoSession session) throws Exception {
- System.out.println("客户端与服务端断开连接.....");
- }
- @Override
- public void sessionCreated(IoSession session) throws Exception {
- // TODO Auto-generated method stub
- System.out
- .println("one Client Connection" + session.getRemoteAddress());
- session.write("我来了······");
- }
- }
先启动服务器,再启动客户端,就ok了
不写客户端也可用
在运行里输入cmd-->telnet localhost 8888 就可以了
解析http请求时报如下错误:
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(Unknown Source) [na:1.6.0_17]
at org.apache.mina.core.buffer.AbstractIoBuffer.getString(AbstractIoBuffer.java:1442) [comet-server.jar:na]
API 中的说明是当输入字节序列对于给定 charset 来说是不合法的,或者输入字符序列不是合法的 16 位 Unicode 序列时,抛出此经过检查的异常。
------解决方法如下
- //创建接受数据的过滤器
- DefaultIoFilterChainBuilder chain = connector.getFilterChain();
- //设定这个过滤器将一行一行(/r/n)的读取数据
- //chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));//这个是传递字符串用的解码器,屏蔽掉
- chain.addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));//这个才是mina传递对象的解码器