mina学习基础-入门实例-传输定长报文(三)
来源:互联网 发布:天猫数据在线直播 编辑:程序博客网 时间:2024/05/16 04:42
Apache的MINA(Multipurpose InfraStructure Networked Application)是一个网络应用框架,
它提供了一个抽象的,事件驱动的异步API,使Java NIO可以在各种传输协议(例如TCP协议和UDP协议)下高效开发.
其中无论是创建mina服务器还是客户端,最重要的三步都是:创建接收器/发送器,添加消息过滤器和添加业务处理器.
其中过滤器是mina的核心,mina提供了很多种过滤器,例如上篇笔记讲到了通过mina提供的ObjectSerializationCodecFactory过滤器传输java对象.
然而在实际项目中由于可能存在两种服务是用不同的语言实现的,例如客户端是用python实现的,那么就不能再使用ObjectSerializationCodecFactory过滤器了.
这种情况下最长用的方式是:传输定长报文,即客户端和服务器规定前n个字节放报文长度,然后客户端向服务器发包,当服务器接收到的报文长度
与预定好的长度相等时,服务器就认为是一条完成的消息.
它提供了一个抽象的,事件驱动的异步API,使Java NIO可以在各种传输协议(例如TCP协议和UDP协议)下高效开发.
其中无论是创建mina服务器还是客户端,最重要的三步都是:创建接收器/发送器,添加消息过滤器和添加业务处理器.
其中过滤器是mina的核心,mina提供了很多种过滤器,例如上篇笔记讲到了通过mina提供的ObjectSerializationCodecFactory过滤器传输java对象.
然而在实际项目中由于可能存在两种服务是用不同的语言实现的,例如客户端是用python实现的,那么就不能再使用ObjectSerializationCodecFactory过滤器了.
这种情况下最长用的方式是:传输定长报文,即客户端和服务器规定前n个字节放报文长度,然后客户端向服务器发包,当服务器接收到的报文长度
与预定好的长度相等时,服务器就认为是一条完成的消息.
1.开发服务器,直接看代码MinaServer.
<span style="font-size:12px;">package com.ilucky.mina.server;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.executor.ExecutorFilter;import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import java.net.InetSocketAddress;import java.util.concurrent.ThreadFactory;import java.util.concurrent.TimeUnit;/** * @author IluckySi * @date 20140528 */public class MinaServer { public static final String HOST = "127.0.0.1"; private static final int PORT = 10061; private static final int BUFFER_SIZE = 8192; private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() { public Thread newThread(final Runnable r) { return new Thread(null, r, "MinaThread2", 64 * 1024); } }; public static void main(String[] args) { try { //创建服务. NioSocketAcceptor acceptor = new NioSocketAcceptor(Runtime.getRuntime().availableProcessors() + 1); //设置缓冲大小. acceptor.getSessionConfig().setReceiveBufferSize(BUFFER_SIZE); //添加线程池. OrderedThreadPoolExecutor executor = new OrderedThreadPoolExecutor(0, 1000, 60, TimeUnit.SECONDS, THREAD_FACTORY); acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(executor)); //添加消息过滤器. acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new XMLProtocolCodecFactory(4))); //添加业务处理器. acceptor.setHandler(new MinaServerIoHandler()); //绑定端口. acceptor.bind(new InetSocketAddress(HOST, PORT)); System.out.println("mina server启动成功!"); } catch (Exception e) { System.out.println("mina server启动失败!"); } }}/**输出结果:mina server启动成功!log4j:WARN No appenders could be found for logger (org.apache.mina.filter.executor.OrderedThreadPoolExecutor).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.服务器收到客户端返回的消息<?xml version="1.0" encoding="UTF-8"?><root><head><author>IluckySi</author><date>20140717 20:35:14</date></head></root>*/</span>
<span style="font-size:12px;">package com.ilucky.mina.server;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;/** * @author IluckySi * @date 20140528 */public class MinaServerIoHandler extends IoHandlerAdapter { public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); System.out.println("服务器收到客户端返回的消息" + msg); session.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +"<root><head><result>success</result></head></root>"); }}</span>
2.开发客户端,直接看代码MinaClient.
<span style="font-size:12px;">package com.ilucky.mina.client;import java.net.InetSocketAddress;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.service.IoConnector;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;import org.apache.mina.transport.socket.nio.NioSocketConnector;/** * @author IluckySi * @date 20140507 */public class MinaClient {public static final String HOST = "127.0.0.1";public static final int PORT = 4000;public static void main(String[] args) {//创建连接器.IoConnector connector = new NioSocketConnector(); //设置超时时间.connector.setConnectTimeoutMillis(30000); //添加消息过滤器connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));//添加业务理器.connector.setHandler(new MinaClientHandler());IoSession session = null;try {//创建连接.ConnectFuture future = connector.connect(new InetSocketAddress(HOST, PORT));// 等待连接创建完成future.awaitUninterruptibly();session = future.getSession();User user = new User();user.setUsername("IluckySi");user.setPassword("123456");session.write(user);System.out.println("客户端向服务器发送消息" + user);;} catch (Exception e) {System.out.println("客户端发送消息失败!");}//等待连接断开, 即线程阻塞在这里, 一直等到服务器关闭此session后, 线程才会继续执行.session.getCloseFuture().awaitUninterruptibly();//释放资源.connector.dispose();}}</span>
<span style="font-size:12px;">package com.ilucky.mina.client;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;/** * @author IluckySi * @date 20140507 */public class MinaClientHandler extends IoHandlerAdapter { public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); System.out.println("客户端收到服务器返回的消息" + msg); }}</span>
3.开发消息解码编码器(服务器端和客户端是一样的),直接看代码:XMLProtocolCodecFactory.
<span style="font-size:12px;">package com.ilucky.mina.server;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFactory;import org.apache.mina.filter.codec.ProtocolDecoder;import org.apache.mina.filter.codec.ProtocolEncoder;/** * @author IluckySi * @date 20140528 */public class XMLProtocolCodecFactory implements ProtocolCodecFactory { private final XMLProtocolEncoder encoder; private final XMLProtocolDecoder decoder; public XMLProtocolCodecFactory(int socketPrefixLength) { encoder = new XMLProtocolEncoder(socketPrefixLength); decoder = new XMLProtocolDecoder(socketPrefixLength); } public ProtocolEncoder getEncoder(IoSession session) throws Exception { return encoder; } public ProtocolDecoder getDecoder(IoSession session) throws Exception { return decoder; }}</span>
<span style="font-size:12px;">package com.ilucky.mina.server;import java.io.InputStream;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.CumulativeProtocolDecoder;import org.apache.mina.filter.codec.ProtocolDecoderOutput;import org.dom4j.Document;import org.dom4j.io.SAXReader;/** * @author IluckySi * @date 20140528 */public class XMLProtocolDecoder extends CumulativeProtocolDecoder { private int socketPrefixLength; public XMLProtocolDecoder(int socketPrefixLength) { this.socketPrefixLength = socketPrefixLength; } @Override protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { try { //prefixedDataAvailable方法是判断得到IoBuffer里的数据是否满足一条消息了. if (!in.prefixedDataAvailable(this.socketPrefixLength, Integer.MAX_VALUE)) {return false;}if (in == null || in.limit() == in.position() || !in.hasRemaining()) {return false;}InputStream is = in.asInputStream();is.read(new byte[this.socketPrefixLength]);SAXReader reader = new SAXReader();Document doc = reader.read(is);out.write(doc.asXML());return true; } catch (Exception e) { System.out.println("服务器解码失败: " + e.toString()); return false; } }}</span>
<span style="font-size:12px;">package com.ilucky.mina.server;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolEncoderAdapter;import org.apache.mina.filter.codec.ProtocolEncoderOutput;import java.nio.charset.Charset;import java.nio.charset.CharsetEncoder;/** * @author IluckySi * @date 20140528 */public class XMLProtocolEncoder extends ProtocolEncoderAdapter { private int socketPrefixLength; public XMLProtocolEncoder(int socketPrefixLength) { this.socketPrefixLength = socketPrefixLength; } public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { CharsetEncoder charsetEncoder = Charset.forName("UTF-8").newEncoder(); String value = ((String) message); IoBuffer buffer = IoBuffer.allocate(64); buffer.setAutoExpand(true); buffer.putPrefixedString(value, this.socketPrefixLength, charsetEncoder); buffer.flip(); out.write(buffer); }}</span>4.测试服务器和客户端.
先启动服务器,再启动客户端,发现客户端成功发送消息,服务器成功接收消息,并成功写回消息给客户端.
点击此处下载源码,亲,免积分的哦!
0 0
- mina学习基础-入门实例-传输定长报文(三)
- mina学习基础-入门实例-传输java对象(二)
- mina学习基础-入门实例-传输以回车做为结尾的字符串(一)
- 定长报文
- 定长报文
- 报文格式【定长报文】
- Mina入门实例
- Apache Mina 入门实例
- Apache Mina 入门实例
- Apache Mina----基础入门
- Mina学习(三):实现简单自定义协议包(报文)
- 学习mina实例~
- Mina入门实例(一)
- MINA 基础学习一
- apache mina 学习(三)-----Mina架构
- apache mina 学习(三)-----Mina架构
- 定长字节报文,字节截取
- 【mina】mina传输对象
- 一些简单的C程序
- 《将博客搬至CSDN》
- 虚拟化(一):虚拟化及vmware产品介绍
- 软件测试技术中测试与调试的概念及…
- 移动开发iOS&Android对比学习--异步处理
- mina学习基础-入门实例-传输定长报文(三)
- TDF8599C特性、参数介绍及TDF8599C样片申请指南
- [ubuntu] setup chrome
- apache与tomcat与weblogic对比
- HDOJ1175 连连看
- Linux网络编程-若干网络基本知识
- [leetcode] Path Sum II
- BFS
- POJ3304-Segments