mina处理断包和粘包
来源:互联网 发布:表格怎么做数据筛选 编辑:程序博客网 时间:2024/05/19 04:02
一. 解码方法
mina中有个内置类CumulativeProtocolDecoder是专门用来处理断包和粘包的。该类的api文档中有个实现的例子。
类org.apache.mina.filter.codec.CumulativeProtocolDecoder
public abstract class CumulativeProtocolDecoder extends ProtocolDecoderAdapter { private final AttributeKey BUFFER = new AttributeKey(getClass(), "buffer"); public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { if (!session.getTransportMetadata().hasFragmentation()) { //用来判断是否还有分帧(断包) while (in.hasRemaining()) { if (!doDecode(session, in, out)) { break; } } return; } ////处理断包,省略 ............................................ } //需要实现的方法 protected abstract boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception;}
CumulativeProtocolDecoder是一个抽象类,必须继承并实现其doDecode方法,用户自定义协议的拆分就应该写在doDecode方法中,下面的类MessageDecoder是一个实现的例子。MessageDecoder解码网络数据到一种有两字节长度头的自定义消息协议格式。
/** * 断包和粘包处理,处理后的消息为一个或多个完整的数据消息 * @author blc */public class MessageDecoder extends CumulativeProtocolDecoder { /* * (non-Javadoc) * * @see * org.apache.mina.filter.codec.CumulativeProtocolDecoder#doDecode(org.apache * .mina.core.session.IoSession, org.apache.mina.core.buffer.IoBuffer, * org.apache.mina.filter.codec.ProtocolDecoderOutput) */ @Override protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { in.order(ServerConfig.ByteEndian); //字节序, ServerConfig.ByteEndian = ByteOrder.LITTLE_ENDIAN //消息buf IoBuffer buf = IoBuffer.allocate(ServerConfig.MessageMaxByte); //ServerConfig.MessageMaxByte 最大消息字节数 buf.order(ServerConfig.ByteEndian); //考虑以下几种情况: // 1. 一个ip包中只包含一个完整消息 // 2. 一个ip包中包含一个完整消息和另一个消息的一部分 // 3. 一个ip包中包含一个消息的一部分 // 4. 一个ip包中包含两个完整的数据消息或更多(循环处理在父类的decode中) if (in.remaining() > 1) { int length = in.getShort(in.position());if (length < 4) { throw new ServerException("Error net message. (Message Length="+length+")"); } if (length > ServerConfig.MessageMaxByte) { throw new ServerException("Error net message. Message Length("+length+") > MessageMaxByte("+ServerConfig.MessageMaxByte+")"); } if (length > in.remaining()) return false; //复制一个完整消息 byte[] bytes = new byte[length]; in.get(bytes); buf.put(bytes); buf.flip(); out.write(buf); return true; } else { return false; } }}
二. 使用
将上面的解码器作为一个过滤器配置到mina中即可,在spring中的配置方法如下:
<!-- 协议过滤器,包括解码和译码 --> <bean id="protocolCodecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter"> <constructor-arg> <bean id="factory" class="server.ClientConnServer.MessageCodecFactory"></bean> </constructor-arg> </bean> <!-- 将协议过滤器配置到mina的过滤链中 --> <bean id="filterChainBuilder" class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder"> <property name="filters"> <map> <entry key="protocolCodecFilter" value-ref="protocolCodecFilter" /> </map> </property> </bean> <!-- 处理器 --> <bean id="clientConnHandler" class="server.ClientConnServer.ClientConnHandler" /> <!-- socket接收器,接收客户端连接 --> <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor" destroy-method="unbind"> <!-- <property name="defaultLocalAddress" value=":161" />--> <property name="handler" ref="clientConnHandler" /> <property name="reuseAddress" value="true" /> <property name="filterChainBuilder" ref="filterChainBuilder" /> </bean>
要配置协议过滤器,必须使用一个ProtocolCodecFactory ,下面是简单实现
public class MessageCodecFactory implements ProtocolCodecFactory { private final MessageEncoder encoder; private final MessageDecoder decoder; public MessageCodecFactory() { encoder = new MessageEncoder(); decoder = new MessageDecoder(); } /* (non-Javadoc) * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getDecoder(org.apache.mina.core.session.IoSession) */ @Override public ProtocolDecoder getDecoder(IoSession session) throws Exception { return decoder; } /* (non-Javadoc) * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getEncoder(org.apache.mina.core.session.IoSession) */ @Override public ProtocolEncoder getEncoder(IoSession session) throws Exception { return encoder; }}/** * 译码器,不做任何事情 */public class MessageEncoder extends ProtocolEncoderAdapter { /* (non-Javadoc) * @see org.apache.mina.filter.codec.ProtocolEncoder#encode(org.apache.mina.core.session.IoSession, java.lang.Object, org.apache.mina.filter.codec.ProtocolEncoderOutput) */ @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { //Do nothing }}
转载地址:http://blianchen.blog.163.com/blog/static/1310562992010101891522100/
- mina处理断包和粘包
- mina处理断包和粘包
- mina处理断包和粘包
- mina学习 粘包,断包处理
- mina IoBuffer 处理断包、粘包
- Mina通信粘包处理
- Mina中的粘包处理
- 深入解析Apache Mina源码(4)——Mina编解码以及对粘包和断包的处理
- mina粘包、多包和少包的解决方法
- Mina 粘包、断包、半包解决
- Socket通信自定义mina 框架过滤器解析(处理粘包、断包问题)
- Apache mina 2.0.1 和 AS3 Socket 进行通讯(处理粘包问题)
- Mina框架断包、粘包问题解决方案
- NIO框架之MINA源码解析(四):粘包与断包处理及编码与解码
- NIO框架之MINA源码解析(四):粘包与断包处理及编码与解码
- NIO框架之MINA源码解析(四):粘包与断包处理及编码与解码
- Mina框架使用---Android客户端的实现,断线重连,粘包处理(服务端非mina)
- mina 粘包解决方案之一
- 链表各类操作详解
- 漫谈QWidget及其派生类(三)
- GLCM
- QWidget及其派生类
- 用JSONKit变换的NSArray用UITableView的数据源总报错的解决方案
- mina处理断包和粘包
- 读入输出优化
- Linux中使用GDB调试NS2
- Webob WSGI 装饰器
- 英国儿童十大宣言
- Oracle 11g 安装过程图文详解
- "undefined reference to" 问题解决方法
- Servlet 中文乱码问题及解决方案剖析
- ACM读入输出优化