- 浏览: 391674 次
- 性别:
- 来自: 深圳
-
文章分类
最新评论
-
Nabulio:
写的详细,特殊语法学习到了
jdk1.5-1.9新特性 -
wooddawn:
您好,最近在做个足球数据库系统,用到了betbrain的数据表 ...
javascript深入理解js闭包 -
lwpan:
很受启发 update也可以
mysql 的delete from 子查询限制 -
wuliaolll:
不错,总算找到原因了
mysql 的delete from 子查询限制
mina的粘包拆包其实是蛮简单的,只是一开始没搞清楚原理。
我们要约定数据包的格式,我这里的是(4个字节长度+json的string字符串)
1:写一个
ProtocolCodecFactory类,用来拦截数据包处理
内容如下
public class MessageCodecFactory implements ProtocolCodecFactory {
private final DataEncoderEx encoder;
private final DataDecoderEx decoder;
public MessageCodecFactory() {
encoder = new DataEncoderEx();
decoder = new DataDecoderEx();
}
/* (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;
}
}
2:在chain里面注册解码器
chain.addLast("codec", new ProtocolCodecFilter(new MessageCodecFactory()));
注意放在多线程上面,否则会导致解码混乱的情况
3:实现decode和encoder
CumulativeProtocolDecoder 这个类的作用很好,我贴一个网上的总结
A. 你的doDecode()方法返回true 时,CumulativeProtocolDecoder 的decode()方法会首
先判断你是否在doDecode()方法中从内部的IoBuffer 缓冲区读取了数据,如果没有,
则会抛出非法的状态异常,也就是你的doDecode()方法返回true 就表示你已经消费了
本次数据(相当于聊天室中一个完整的消息已经读取完毕),进一步说,也就是此时你
必须已经消费过内部的IoBuffer 缓冲区的数据(哪怕是消费了一个字节的数据)。如果
验证过通过,那么CumulativeProtocolDecoder 会检查缓冲区内是否还有数据未读取,
如果有就继续调用doDecode()方法,没有就停止对doDecode()方法的调用,直到有新
的数据被缓冲。
B. 当你的doDecode()方法返回false 时,CumulativeProtocolDecoder 会停止对doDecode()
方法的调用,但此时如果本次数据还有未读取完的,就将含有剩余数据的IoBuffer 缓
冲区保存到IoSession 中,以便下一次数据到来时可以从IoSession 中提取合并。如果
发现本次数据全都读取完毕,则清空IoBuffer 缓冲区。
简而言之,当你认为读取到的数据已经够解码了,那么就返回true,否则就返回false。这
个CumulativeProtocolDecoder 其实最重要的工作就是帮你完成了数据的累积,因为这个工
作是很烦琐的。
也就是说返回true,那么CumulativeProtocolDecoder会再次调用decoder,并把剩余的数据发下来
返回false就不处理剩余的,当有新数据包来的时候把剩余的和新的拼接在一起然后再调用decoder
public class DataDecoderEx extends CumulativeProtocolDecoder {
@Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
// TODO Auto-generated method stub
if(in.remaining()<4)//这里很关键,网上很多代码都没有这句,是用来当拆包时候剩余长度小于4的时候的保护,不加就出错咯
{
return false;
}
if (in.remaining() > 1) {
in.mark();//标记当前位置,以便reset
int length =in.getInt(in.position());
if(length > in.remaining()-4){//如果消息内容不够,则重置,相当于不读取size
System.out.println("package notenough left="+in.remaining()+" length="+length);
in.reset();
return false;//接收新数据,以拼凑成完整数据
}else{
System.out.println("package ="+in.toString());
in.getInt();
byte[] bytes = new byte[length];
in.get(bytes, 0, length);
String str = new String(bytes,"UTF-8");
if(null != str && str.length() > 0){
String strOut = DateSecret.decryptDES(str);//别看这里的处理,这里是我的数据包解密算法~你可以直接拿str当数据
out.write(strOut);
}
if(in.remaining() > 0){//如果读取内容后还粘了包,就让父类再给一次,进行下一次解析
//System.out.println("package left="+in.remaining()+" data="+in.toString());
}
return true;//这里有两种情况1:没数据了,那么就结束当前调用,有数据就再次调用
}
}
return false;//处理成功,让父类进行接收下个包
}
}
public class DataEncoderEx 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)
*/
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
System.out.println(message);
IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
String strOut = DateSecret.encryptDES(message.toString());//别看这里的处理,这里是我的数据包加密算法~你可以直接拿message.toString当数据
buf.putInt(strOut.getBytes(Charset.forName("utf-8")).length);
buf.putString(strOut,Charset.forName("utf-8").newEncoder());
buf.flip();
out.write(buf);
}
}
这样基本没神马问题,如有问题我会继续补充
我们要约定数据包的格式,我这里的是(4个字节长度+json的string字符串)
1:写一个
ProtocolCodecFactory类,用来拦截数据包处理
内容如下
public class MessageCodecFactory implements ProtocolCodecFactory {
private final DataEncoderEx encoder;
private final DataDecoderEx decoder;
public MessageCodecFactory() {
encoder = new DataEncoderEx();
decoder = new DataDecoderEx();
}
/* (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;
}
}
2:在chain里面注册解码器
chain.addLast("codec", new ProtocolCodecFilter(new MessageCodecFactory()));
注意放在多线程上面,否则会导致解码混乱的情况
3:实现decode和encoder
CumulativeProtocolDecoder 这个类的作用很好,我贴一个网上的总结
A. 你的doDecode()方法返回true 时,CumulativeProtocolDecoder 的decode()方法会首
先判断你是否在doDecode()方法中从内部的IoBuffer 缓冲区读取了数据,如果没有,
则会抛出非法的状态异常,也就是你的doDecode()方法返回true 就表示你已经消费了
本次数据(相当于聊天室中一个完整的消息已经读取完毕),进一步说,也就是此时你
必须已经消费过内部的IoBuffer 缓冲区的数据(哪怕是消费了一个字节的数据)。如果
验证过通过,那么CumulativeProtocolDecoder 会检查缓冲区内是否还有数据未读取,
如果有就继续调用doDecode()方法,没有就停止对doDecode()方法的调用,直到有新
的数据被缓冲。
B. 当你的doDecode()方法返回false 时,CumulativeProtocolDecoder 会停止对doDecode()
方法的调用,但此时如果本次数据还有未读取完的,就将含有剩余数据的IoBuffer 缓
冲区保存到IoSession 中,以便下一次数据到来时可以从IoSession 中提取合并。如果
发现本次数据全都读取完毕,则清空IoBuffer 缓冲区。
简而言之,当你认为读取到的数据已经够解码了,那么就返回true,否则就返回false。这
个CumulativeProtocolDecoder 其实最重要的工作就是帮你完成了数据的累积,因为这个工
作是很烦琐的。
也就是说返回true,那么CumulativeProtocolDecoder会再次调用decoder,并把剩余的数据发下来
返回false就不处理剩余的,当有新数据包来的时候把剩余的和新的拼接在一起然后再调用decoder
public class DataDecoderEx extends CumulativeProtocolDecoder {
@Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
// TODO Auto-generated method stub
if(in.remaining()<4)//这里很关键,网上很多代码都没有这句,是用来当拆包时候剩余长度小于4的时候的保护,不加就出错咯
{
return false;
}
if (in.remaining() > 1) {
in.mark();//标记当前位置,以便reset
int length =in.getInt(in.position());
if(length > in.remaining()-4){//如果消息内容不够,则重置,相当于不读取size
System.out.println("package notenough left="+in.remaining()+" length="+length);
in.reset();
return false;//接收新数据,以拼凑成完整数据
}else{
System.out.println("package ="+in.toString());
in.getInt();
byte[] bytes = new byte[length];
in.get(bytes, 0, length);
String str = new String(bytes,"UTF-8");
if(null != str && str.length() > 0){
String strOut = DateSecret.decryptDES(str);//别看这里的处理,这里是我的数据包解密算法~你可以直接拿str当数据
out.write(strOut);
}
if(in.remaining() > 0){//如果读取内容后还粘了包,就让父类再给一次,进行下一次解析
//System.out.println("package left="+in.remaining()+" data="+in.toString());
}
return true;//这里有两种情况1:没数据了,那么就结束当前调用,有数据就再次调用
}
}
return false;//处理成功,让父类进行接收下个包
}
}
public class DataEncoderEx 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)
*/
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
System.out.println(message);
IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
String strOut = DateSecret.encryptDES(message.toString());//别看这里的处理,这里是我的数据包加密算法~你可以直接拿message.toString当数据
buf.putInt(strOut.getBytes(Charset.forName("utf-8")).length);
buf.putString(strOut,Charset.forName("utf-8").newEncoder());
buf.flip();
out.write(buf);
}
}
这样基本没神马问题,如有问题我会继续补充
发表评论
-
将json格式的字符数组转为List对象
2015-08-10 15:18 910使用的是json-lib.jar包 将json格式的字符数组 ... -
用httpPost对JSON发送和接收的例子
2015-08-10 11:16 1106HTTPPost发送JSON: private static ... -
zookeeper适用场景:zookeeper解决了哪些问题
2015-07-31 18:01 766问题导读: 1.master挂机� ... -
java泛型
2015-07-29 10:48 774什么是泛型? 泛型(Ge ... -
Java线程Dump分析工具--jstack
2015-06-23 11:09 731jstack用于打印出给定的java进程ID或core fil ... -
什么是spark?
2015-04-10 09:37 499关于Spark: Spark是UC Berkeley AM ... -
dubbo 教程
2015-04-09 19:21 785先给出阿里巴巴dubbo的� ... -
jre/bin目录下面工具说明
2015-03-20 16:45 638jre/bin目录下面工具说明 ... -
JVM系列三:JVM参数设置、分析
2015-01-30 11:18 705不管是YGC还 ... -
jstat使用
2015-01-27 11:11 682jstat 1. jstat -gc pid ... -
查看java堆栈情况(cpu占用过高)
2015-01-27 11:10 7491. 确定占用cpu高的线程id: 方法一: 直接使用 ps ... -
慎用ArrayList的contains方法,使用HashSet的contains方法代替
2015-01-20 14:14 1151在启动一个应用的时候,发现其中有一处数据加载要数分钟,刚开始 ... -
Java虚拟机工作原理详解
2015-01-16 10:00 724一、类加载器首先来� ... -
jdk1.5-1.9新特性
2014-11-11 10:22 83671.51.自动装箱与拆箱:2.枚举(常用来设计单例模式 ... -
java动态代理(JDK和cglib)
2014-09-24 15:51 480JAVA的动态代理 代理模式 代理模式是常用的java设计 ... -
Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
2014-09-24 15:45 703class文件简介及加载 Java编译器编译 ... -
怎么用github下载资源
2014-09-24 11:18 4581、下载github:到http://windows. ... -
maven项目时jar包没有到lib目录下
2014-09-01 20:05 2605在建项目时路径都设置好了,为什么在eclipse中运行mav ... -
使用并行计算大幅提升递归算法效率
2014-08-27 15:04 608前言: 无论什么样的� ... -
JAVA 实现FTP
2014-08-22 14:41 709一个JAVA 实现FTP功能的代码,包括了服务器的设置模块, ...
相关推荐
《MINA使用札记——CumulativeProtocolDecoder使用详解》 MINA(Java Multithreaded Network Application Framework)是一个强大的、高性能的Java网络应用框架,它主要用于构建可伸缩的、高性能的服务端应用,如...
Apache Mina是一个开源的网络通信应用框架,主要应用于Java平台,它为高性能、高可用性的网络应用程序提供了基础架构。在本文中,我们将深入探讨Mina的高级使用,特别是在文件图片传送、文件发送、XML和JSON报文处理...
Apache Mina是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个"apache-mina-2.0.4.rar"压缩包包含的是Apache Mina 2.0.4版本的源代码,是深入理解和定制Mina的...
Apache Mina是一个开源的网络通信框架,常用于构建高性能、高效率的服务端应用程序,尤其在Java平台上。在本文中,我们将深入探讨Mina的核心概念,包括连接管理、心跳机制以及断线重连策略。 首先,让我们理解"Mina...
MINA (Java IO Network Application Framework) 是一个由Apache软件基金会开发的开源网络通信框架,主要应用于构建高性能、高可用性的网络服务器。这个压缩包包含了MINA API文档、自学手册以及开发指南,对于学习和...
Mina和Socket是两种常见的网络通信框架和技术,它们在Java编程环境中被广泛使用。本篇文章将深入探讨如何使用Mina与Socket实现通信,并提供客户端和服务端的实现代码概述。 Mina(全称“MINA: Minimalistic ...
mina-core-2.0.0-M6.jar mina-example-2.0.0-M6.jar mina-filter-codec-netty-2.0.0-M6.jar mina-filter-compression-2.0.0-M6.jar mina-integration-beans-2.0.0-M6.jar mina-integration-jmx-2.0.0-M6.jar mina-...
Java SpringBoot 整合Mina框架,涉及到的核心技术主要包括Java NIO(非阻塞I/O)、Mina框架以及SpringBoot的集成应用。本教程旨在帮助开发者深入理解和掌握这些技术,并提供了一个可直接使用的基础平台框架。 Java ...
mina新手案例,mina新手教程源码 mina+springboot最简单的案例。用的IDEA * mina服务端 * 1、添加@Controller注解和 @PostConstruct注解,代表启动springboot项目时也调用该类下的该方法, * 启动springboot项目...
标题中的“给予mina协议进行大数据传输”指的是一种基于Java的网络通信框架——Apache MINA(Model-View-Controller for Network Applications)。MINA是Apache软件基金会的一个项目,它提供了一个高度可扩展和高...
Apache Mina是一个高度可扩展的网络通信框架,它允许开发者创建高性能、高效率的服务端和客户端应用程序。在Java世界中,Mina以其简洁的API和灵活性而受到青睐,尤其适用于处理大量的并发连接,如TCP/IP和UDP协议。...
**mina自定义编解码器详解** mina是一个Java开发的网络通信框架,广泛应用于TCP和UDP协议的服务器和客户端开发。在mina框架中,编解码器(Codec)扮演着至关重要的角色,它负责将应用层的数据转换为网络传输的字节...
**Spring Boot 整合Mina实现串口通信详解** 在Java开发中,有时我们需要与硬件设备进行串口通信,例如读取传感器数据或控制工业设备。Spring Boot作为一款轻量级的框架,使得快速构建应用变得简单。而Mina则是一款...
Apache Mina是一个高度可扩展的Java网络通信框架,它提供了简单而强大的开发接口,用于创建高性能、高效率的网络应用程序。Mina的核心理念是将网络协议处理与业务逻辑分离,使得开发者可以专注于实现应用程序的业务...
在本文中,我们将深入探讨如何将Spring Boot与Mina进行深度整合,以便为新手开发者提供一个开箱即用的解决方案。Spring Boot以其简洁的配置和快速的开发体验,已经成为Java领域中的主流微服务框架,而Mina则是一个...
**Android-MinaSocket:基于Mina的高效Socket长连接库** 在移动应用开发中,尤其是Android平台,实时性与稳定性是许多应用场景的核心需求,比如在线游戏、即时通讯、物联网设备等。在这种背景下,使用Socket进行长...
Apache Mina是一个开源项目,它提供了一个高度可扩展的网络通信框架,用于简化开发高性能、高可用性的网络服务器和客户端应用程序。"Mina demo mina jar包"指的是使用Apache Mina框架创建的一个演示示例,这个示例...
Apache Mina是一个开源的网络通信框架,主要用于简化Java应用程序与远程服务器之间的通信。它提供了高度可扩展和高性能的网络协议处理能力,支持多种传输层协议,如TCP/IP、UDP/IP和SSL/TLS等。在本示例中,我们关注...
Apache Mina是一个强大的网络通信框架,专为基于TCP/IP和UDP/IP协议栈的应用设计。它提供了JAVA对象的序列化和虚拟机内部通信的功能,使得开发者能够迅速构建高性能、高可扩展性的网络应用。Mina的核心特性是其事件...
mina心跳包机制是Apache Mina框架中的一个关键特性,它用于维持网络连接的活跃状态,确保数据能够在客户端和服务端之间顺畅地传输。Mina是一个高度可扩展的Java网络应用框架,广泛应用于各种分布式系统和网络服务,...