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 {@Overridepublic void exceptionCaught(IoSession session, Throwable cause)throws Exception {System.out.println("exceptionCaught");}@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {String s = (String) message;System.out.println("messageReceived: " + s);}@Overridepublic void messageSent(IoSession session, Object message) throws Exception {System.out.println("messageSent");}@Overridepublic void sessionClosed(IoSession session) throws Exception {System.out.println("sessionClosed");}@Overridepublic void sessionCreated(IoSession session) throws Exception {System.out.println("sessionCreated");}@Overridepublic void sessionIdle(IoSession session, IdleStatus status)throws Exception {System.out.println("sessionIdle");}@Overridepublic 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.服务器端口启动起来,监听9898acceptor.bind(new InetSocketAddress(9898));} catch (IOException e) {e.printStackTrace();}}}
public class MyServerHandler extends IoHandlerAdapter {@Overridepublic void exceptionCaught(IoSession session, Throwable cause)throws Exception {System.out.println("exceptionCaught");}@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {String s = (String) message;System.out.println("messageReceived: " + s);session.write("server reply: " + s);}@Overridepublic void messageSent(IoSession session, Object message) throws Exception {System.out.println("messageSent");}@Overridepublic void sessionClosed(IoSession session) throws Exception {System.out.println("sessionClosed");}@Overridepublic void sessionCreated(IoSession session) throws Exception {System.out.println("sessionCreated");}
//客户端进入空闲状态,检测 客户端 是否掉线@Overridepublic void sessionIdle(IoSession session, IdleStatus status)throws Exception {System.out.println("sessionIdle");}@Overridepublic 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();}@Overridepublic ProtocolDecoder getDecoder(IoSession arg0) throws Exception {return mCumulativeDecoder;}@Overridepublic ProtocolEncoder getEncoder(IoSession arg0) throws Exception {return mEncoder;}}
public class MyTextLineCumulativeDecoder extends CumulativeProtocolDecoder {@Overrideprotected boolean doDecode(IoSession session, IoBuffer in,ProtocolDecoderOutput out) throws Exception {int startPosition = in.position();while (in.hasRemaining()) {byte b = in.get();if (b == '\n') {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 {@Overridepublic void dispose(IoSession arg0) throws Exception {}@Overridepublic 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 {@Overridepublic void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)throws Exception {int startPosition = in.position();while (in.hasRemaining()) {byte b = in.get();if (b == '\n') {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);}}}@Overridepublic void dispose(IoSession arg0) throws Exception {}@Overridepublic void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)throws Exception {}}