Apache Mina Server 是一个网络通信应用框架,对socket进行了封装。
http://www.cnblogs.com/moonandstar08/p/5475766.html
http://blog.csdn.net/u010739551/article/details/47361365
http://www.cnblogs.com/yanghuiping/p/4108063.html (mina 自定义编解码)
Client端:
public class MinaClient { public static void main(String[] args) throws Exception{
//1. NioSocketConnector connector = new NioSocketConnector();
//2. connector.setHandler(new MyClientHandler());
//3.所有收发的消息都会经过拦截器,经拦截器进行消息的处理 connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
//4. ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", 9898)); future.awaitUninterruptibly(); IoSession session = future.getSession(); BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in)); String inputContent; while (!(inputContent = inputReader.readLine()).equals("bye")) { session.write(inputContent); } } }
将网络和消息处理的代码分开
public class MyClientHandler extends IoHandlerAdapter { @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { System.out.println("exceptionCaught"); } @Override public void messageReceived(IoSession session, Object message) throws Exception { String s = (String) message; System.out.println("messageReceived: " + s); } @Override public void messageSent(IoSession session, Object message) throws Exception { System.out.println("messageSent"); } @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("sessionClosed"); } @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("sessionCreated"); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("sessionIdle"); } @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("sessionOpened"); } }
Server端:
public class MinaServer { public static void main(String[] args) { try { //1. NioSocketAcceptor acceptor = new NioSocketAcceptor(); //2.网络管理和消息处理的分割开来; MyServerHandler()专门处理消息分发和会话管理 acceptor.setHandler(new MyServerHandler()); //3.拦截器,责任链设计模式。所有收发的消息全部要经过拦截器过滤之后,消息才可以收发; //网络上传输是字节,拦截器做对象的转换工作; //ProtocolCodecFilter 二进制数据和对象进行转化;MyTextLineFactory()内置的,对传输数据进行加解码 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MyTextLineFactory())); //每隔5秒,检查客户端是否处于空闲狂态,检测客户端是否掉线 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5); //4.服务器端口启动起来,监听9898 acceptor.bind(new InetSocketAddress(9898)); } catch (IOException e) { e.printStackTrace(); } } }
public class MyServerHandler extends IoHandlerAdapter { @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { System.out.println("exceptionCaught"); } @Override public void messageReceived(IoSession session, Object message) throws Exception { String s = (String) message; System.out.println("messageReceived: " + s); session.write("server reply: " + s); } @Override public void messageSent(IoSession session, Object message) throws Exception { System.out.println("messageSent"); } @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("sessionClosed"); } @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("sessionCreated"); }
//客户端进入空闲状态,检测 客户端 是否掉线 @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("sessionIdle"); } @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("sessionOpened"); } }
public class MyTextLineFactory implements ProtocolCodecFactory { private MyTextLineDecoder mDecoder; private MyTextLineCumulativeDecoder mCumulativeDecoder; private MyTextLineEncoder mEncoder; public MyTextLineFactory () { mDecoder = new MyTextLineDecoder(); mEncoder = new MyTextLineEncoder(); mCumulativeDecoder = new MyTextLineCumulativeDecoder(); } @Override public ProtocolDecoder getDecoder(IoSession arg0) throws Exception { return mCumulativeDecoder; } @Override public ProtocolEncoder getEncoder(IoSession arg0) throws Exception { return mEncoder; } }
public class MyTextLineCumulativeDecoder extends CumulativeProtocolDecoder { @Override protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { int startPosition = in.position(); while (in.hasRemaining()) { byte b = in.get(); if (b == ' ') { int currentPositoin = in.position(); int limit = in.limit(); in.position(startPosition); in.limit(currentPositoin); IoBuffer buf = in.slice(); byte [] dest = new byte[buf.limit()]; buf.get(dest); String str = new String(dest); out.write(str); in.position(currentPositoin); in.limit(limit); return true; } } in.position(startPosition); return false; } }
public class MyTextLineEncoder implements ProtocolEncoder { @Override public void dispose(IoSession arg0) throws Exception { } @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { String s =null; if (message instanceof String) { s = (String) message; } if (s != null) { CharsetEncoder charsetEndoer = (CharsetEncoder)session.getAttribute("encoder"); if (charsetEndoer == null) { charsetEndoer = Charset.defaultCharset().newEncoder(); session.setAttribute("encoder", charsetEndoer); } IoBuffer ioBuffer = IoBuffer.allocate(s.length()); ioBuffer.setAutoExpand(true); ioBuffer.putString(s, charsetEndoer); ioBuffer.flip(); out.write(ioBuffer); } } }
public class MyTextLineDecoder implements ProtocolDecoder { @Override public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { int startPosition = in.position(); while (in.hasRemaining()) { byte b = in.get(); if (b == ' ') { int currentPositoin = in.position(); int limit = in.limit(); in.position(startPosition); in.limit(currentPositoin); IoBuffer buf = in.slice(); byte [] dest = new byte[buf.limit()]; buf.get(dest); String str = new String(dest); out.write(str); in.position(currentPositoin); in.limit(limit); } } } @Override public void dispose(IoSession arg0) throws Exception { } @Override public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1) throws Exception { } }