为什么80%的码农都做不了架构师?>>>   

一.  解码方法
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解码网络数据到一种有两字节长度头的自定义消息协议格式。

/*** 断包和粘包处理,处理后的消息为一个或多个完整的数据消息*/
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)*/@Overrideprotected boolean doDecode(IoSession session, IoBuffer in,ProtocolDecoderOutput out) throws Exception {in.order(ServerConfig.ByteEndian);    //字节序, ServerConfig.ByteEndian = ByteOrder.LITTLE_ENDIAN//消息bufIoBuffer 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)*/@Overridepublic ProtocolDecoder getDecoder(IoSession session) throws Exception {return decoder;}/* (non-Javadoc)* @see org.apache.mina.filter.codec.ProtocolCodecFactory#getEncoder(org.apache.mina.core.session.IoSession)*/@Overridepublic 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)*/@Overridepublic void encode(IoSession session, Object message,ProtocolEncoderOutput out) throws Exception {//Do nothing}}

转载于:https://my.oschina.net/leoson/blog/105681

mina处理断包和粘包相关推荐

  1. 完美解决Python套接字编程时TCP断包与粘包问题

    首先,来看一个代码,使用TCP协议,发送端发送一句话,接收端接收并显示,运行完全正常. 接下来,把客户端代码稍微修改一下,连续发送多个数据, 按照正常的想法,在服务端输出的信息应该是分为多行的,这样才 ...

  2. socket的长连接、短连接、半包、粘包与分包

    socket的半包,粘包与分包的问题和处理代码:http://blog.csdn.net/qq_16112417/article/details/50392463 知乎关于长连接和短连接:https: ...

  3. Python之网络编程(粘包、粘包解决方案)

    文章目录 tcp粘包 第一种粘包 第二种粘包 udp粘包 解决粘包现象 粘包现象是指发送方发送的若干数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.粘包现象只会在tcp ...

  4. (P9)socket编程四:流协议与粘(nian)包,粘包产生的原因,粘包处理方案,readn,writen 6.回射客户/服务器

    文章目录 1.流协议与粘(nian)包 2.粘包产生的原因 4.粘包处理方案 5.readn,writen 6.回射客户/服务器 1.流协议与粘(nian)包 tcp是基于字节流的传输服务(字节流是无 ...

  5. java socket解决半包、粘包问题

    java socket解决半包.粘包问题 一.java socket出现半包.粘包问题原因及解决见博客: http://www.cnblogs.com/solq/p/4315763.html http ...

  6. Netty处理TCP半包和粘包问题

    Netty在RPC中充当着重要的核心角色,封装了对JDK NIO的复杂操作. TCP连接中存在半包和粘包问题,其历史原因不在追究,Netty在对问题处理上提供了现有的模板方法,用户需要自己定义编码和解 ...

  7. 坑人无数的俩货:半包和粘包

    顾名思义,就是收到了半个包,这个时候不足以组成一个应用层的包.就像你要对你喜欢的人说"我喜欢你",但是因为喝水咽着了,第一次只说了"我"字,第二次说了个&quo ...

  8. dubbo的半包和粘包

    若出现粘包,就会根据它的请求长度进行截取: 若出现拆包,数据会不完整,就进入循环重新读取,直到取到完整数据. 一.前言 在客户端与服务端进行通信时候都会约定一个通讯协议,协议一般包含一个header和 ...

  9. Mina学习(4):实现自定义编解码器并解决半包,丢包,粘包问题

    一.编码器:将要发送的数据转化成byte[] 进行传输 自定义编码器的实现: package filter;import org.apache.mina.core.buffer.IoBuffer; i ...

最新文章

  1. 阿里云服务器Linux配置数据库、jre、tomcat、部署javaweb
  2. linux变量中代,linux中shell变量$#,$@,$0,$1,$2和变量${0%/*}
  3. php7 返回值,7.6.4 函数返回值
  4. ElasticSearch面试 - es 写入数据的工作原理是什么啊?
  5. 让你每天抽出两小时陪小孩子读书,你能坚持吗?
  6. 10张精美可视化大屏模板分享,加极简制作攻略!抓紧收藏
  7. 微软VMM2008实战之P2V迁移攻略
  8. 基于分布式光纤传感的高压电力线路异常监测探讨
  9. matlab前馈仿真,前馈-反馈控制系统的具体分析及其MATLAB/Simulink.PDF
  10. jspdf打印、pdf打印
  11. 微信小程序开发详细步骤是什么?
  12. HTML+CSS期末网页课设——游戏宣传网页(全部源码)
  13. 美工设计怎样可以提高自己设计能力
  14. 某android广告SDK逆向分析总结
  15. 机场航班信息显示系统
  16. Android今日头条的适配
  17. 道翰天琼认知智能为您解密:Rust语言杀疯了!前有谷歌高薪争夺 Rust 人才,Facebook再官宣加入Rust基金会 「自2016年以来,Facebook 就已开始使用 Rust,并应用在开发
  18. apicloud 预览图片_APICloud(三):预览图片
  19. TMT行业有7个子行业
  20. JAVA学习从软件工程导论课自动出题软件编程项目开始

热门文章

  1. 简单了解request与response
  2. 分布式服务化系统一致性的“最佳实干”
  3. Java 源代码和 C 源代码的运行区别
  4. 数据结构~总结与文章目录
  5. PLSQL基础语法二-流程控制,循环
  6. 29个月过去了,CSDN排名前200了:排名不断靠前的过程中,自己的技术水平和竞争力一定会不断向上...
  7. sys_guid 点滴用法
  8. Java基础-时间复杂度计算方式
  9. Python:打印目录下最大的十个文件
  10. Attention Mechanism