- 浏览: 949445 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
MINA 编解码器实例:http://donald-draper.iteye.com/blog/2375317
Mina Socket与报文过滤链:http://donald-draper.iteye.com/blog/2376440
Mina 协议编解码过滤器一(协议编解码工厂、协议编码器):
http://donald-draper.iteye.com/blog/2376663
Mina 协议编解码过滤器二(协议解码器):
http://donald-draper.iteye.com/blog/2376679
Mina 队列Queue:http://donald-draper.iteye.com/blog/2376712
Mina 协议编解码过滤器三(会话write与消息接收过滤):
http://donald-draper.iteye.com/blog/2376818
前面我们看了一下协议编解码器,在编解码器实例这篇文章中,用的编码器不是ProtocolDecoderAdapter而是CumulativeProtocolDecoder,今天我们就来看一下可累积性协议解码器:
总结:
累积性协议解码器decode方法,首先从会话获取属性BUFFER对应的buffer,如果会话缓存buffer不为null,则将当前in(ByteBuffer)的内容放到会话缓存buffer中;//否直接使用当前in(ByteBuffer),将是否开启会话缓存buffer,置为否;循环尝试使用doDecode方法解码数据,直到doDecode方法返回false,如果doDecode方法返回true,则继续调用doDecode方法解码数据,如果在一次解码数据返回true,但buffer中还有数据,则根据是否开启会话缓存buffer决定将buffer数据进行压缩还是存储在会话中;如果在一次解码数据返回true,但buffer中没有数据,则从会话中移除属性BUFFER,并释放对应的buffer空间。doDecode方法放抽象方法待类型实现。CumulativeProtocolDecoder实现可累性方法主要是通过将buffer存储在会话中,以实现接收数据的可累计性。
Mina Socket与报文过滤链:http://donald-draper.iteye.com/blog/2376440
Mina 协议编解码过滤器一(协议编解码工厂、协议编码器):
http://donald-draper.iteye.com/blog/2376663
Mina 协议编解码过滤器二(协议解码器):
http://donald-draper.iteye.com/blog/2376679
Mina 队列Queue:http://donald-draper.iteye.com/blog/2376712
Mina 协议编解码过滤器三(会话write与消息接收过滤):
http://donald-draper.iteye.com/blog/2376818
前面我们看了一下协议编解码器,在编解码器实例这篇文章中,用的编码器不是ProtocolDecoderAdapter而是CumulativeProtocolDecoder,今天我们就来看一下可累积性协议解码器:
/** * A {@link ProtocolDecoder} that cumulates the content of received * buffers to a [i]cumulative buffer[/i] to help users implement decoders. * <p>CumulativeProtocolDecoder累计接收的数据到一个累计性的buffer中,以帮助使用解码数据。 * If the received {@link ByteBuffer} is only a part of a message. * decoders should cumulate received buffers to make a message complete or * to postpone decoding until more buffers arrive. * <p>如果接收的数据只是消息的一部分,解码器应该累计接收的buffer,直到消息传输完成, 或者退出解码,直到更多的buffer到达。 * Here is an example decoder that decodes CRLF terminated lines into * <code>Command</code> objects: * <pre>这里是一个使用CRLF为行结束符的解码器 * public class CRLFTerminatedCommandLineDecoder * extends CumulativeProtocolDecoder { * * private Command parseCommand(ByteBuffer in) { * // Convert the bytes in the specified buffer to a * // Command object. * ... * } * * protected boolean doDecode(IoSession session, ByteBuffer in, * ProtocolDecoderOutput out) * throws Exception { * * // Remember the initial position. * int start = in.position(); * * // Now find the first CRLF in the buffer. * byte previous = 0; * while (in.hasRemaining()) { * byte current = in.get(); * * if (previous == '\r' && current == '\n') { * // Remember the current position and limit. //记录当前位置和limit * int position = in.position(); * int limit = in.limit(); * try { * in.position(start); * in.limit(position); * // The bytes between in.position() and in.limit() * // now contain a full CRLF terminated line.解析命令 * out.write(parseCommand(in.slice())); * } finally { * // Set the position to point right after the * // detected line and set the limit to the old * // one.解码后恢复position,limit位置 * in.position(position); * in.limit(limit); * } * // Decoded one line; CumulativeProtocolDecoder will * // call me again until I return false. So just * // return true until there are no more lines in the * // buffer.解码一行数据;累计协议解码再次调用doDecode,直到doDecode返回false; //则返回true,直到在buffer中,不再有一行数据, * return true; * } * * previous = current; * } * 如果在buffer中,没有发现换行符,则重置position位置为start * // Could not find CRLF in the buffer. Reset the initial * // position to the one we recorded above. * in.position(start); * * return false; * } * } * </pre> * * @author The Apache Directory Project (mina-dev@directory.apache.org) * @version $Rev$, $Date$ */ public abstract class CumulativeProtocolDecoder extends ProtocolDecoderAdapter { private static final String BUFFER = CumulativeProtocolDecoder.class .getName() + ".Buffer"; /** * Creates a new instance. */ protected CumulativeProtocolDecoder() { } /** * Cumulates content of <tt>in</tt> into internal buffer and forwards * decoding request to {@link #doDecode(IoSession, ByteBuffer, ProtocolDecoderOutput)}. * <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt> * and the cumulative buffer is compacted after decoding ends. * 累计数据放在内部buffer in中,转发解码请求到#doDecode方法,在#doDecode方法返回false之前, 重复调用#doDecode方法解码内部in缓存数据,在每次解码结束,如果buffer中还有没解码完的数据,则 压缩可累计buffer。 * @throws IllegalStateException if your <tt>doDecode()</tt> returned * <tt>true</tt> not consuming the cumulative buffer. */ public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { boolean usingSessionBuffer = true;//是否开启会话缓存buffer ByteBuffer buf = (ByteBuffer) session.getAttribute(BUFFER);//从会话获取属性BUFFER对应的buffer // If we have a session buffer, append data to that; otherwise // use the buffer read from the network directly. if (buf != null) { //如果会话缓存buffer不为null,则将当前in(ByteBuffer)的内容放到会话缓存buffer中 buf.put(in); buf.flip();//读写模式切换 } else { //否则直接使用当前in(ByteBuffer),将是否开启会话缓存buffer,置为否。 buf = in; usingSessionBuffer = false; } for (;;) { int oldPos = buf.position(); //调用doDecode解码buffer boolean decoded = doDecode(session, buf, out); if (decoded) { //解码成功 if (buf.position() == oldPos) { throw new IllegalStateException( "doDecode() can't return true when buffer is not consumed."); } if (!buf.hasRemaining()) { //如果buffer中还有数据没解码,则跳出当前循环 break; } } else { //否则继续尝试解码 break; } } // if there is any data left that cannot be decoded, we store // it in a buffer in the session and next time this decoder is // invoked the session buffer gets appended to //如果buffer中的数据没有解码完,则存储在会话中,以便下次解码器,将遗留的数据与 //接收的数据一起解码 if (buf.hasRemaining()) { if (usingSessionBuffer) //使用缓存,则压缩buffer,将为解码的数据移到buffer的头部 buf.compact(); else //否则存储在会话中 storeRemainingInSession(buf, session); } else { //如果buffer中没有数据,且开启会话缓存buffer,则从会话中移除属性BUFFER, //并释放对应的buffer空间 if (usingSessionBuffer) removeSessionBuffer(session); } } /** * Implement this method to consume the specified cumulative buffer and * decode its content into message(s). * 实现此方法,用于消费累积性buffer中的数据,解码数据为上层消息对象。 * @param in the cumulative buffer * @return <tt>true</tt> if and only if there's more to decode in the buffer * and you want to have <tt>doDecode</tt> method invoked again. * Return <tt>false</tt> if remaining data is not enough to decode, * then this method will be invoked again when more data is cumulated. * @throws Exception if cannot decode <tt>in</tt>. //待子类扩展 */ protected abstract boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception; /** * Releases the cumulative buffer used by the specified <tt>session</tt>. * Please don't forget to call <tt>super.dispose( session )</tt> when * you override this method. 释放会话的可累计性缓存buffer,当重写此方法,不要忘了调用super.dispose( session )。 */ public void dispose(IoSession session) throws Exception { removeSessionBuffer(session); } //从会话中移除属性BUFFER,并释放对应的buffer空间 private void removeSessionBuffer(IoSession session) { ByteBuffer buf = (ByteBuffer) session.removeAttribute(BUFFER); if (buf != null) { buf.release(); } } //将buffer存储在会话属性BUFFER中 private void storeRemainingInSession(ByteBuffer buf, IoSession session) { ByteBuffer remainingBuf = ByteBuffer.allocate(buf.capacity()); remainingBuf.setAutoExpand(true); remainingBuf.order(buf.order()); remainingBuf.put(buf); session.setAttribute(BUFFER, remainingBuf); } }
总结:
累积性协议解码器decode方法,首先从会话获取属性BUFFER对应的buffer,如果会话缓存buffer不为null,则将当前in(ByteBuffer)的内容放到会话缓存buffer中;//否直接使用当前in(ByteBuffer),将是否开启会话缓存buffer,置为否;循环尝试使用doDecode方法解码数据,直到doDecode方法返回false,如果doDecode方法返回true,则继续调用doDecode方法解码数据,如果在一次解码数据返回true,但buffer中还有数据,则根据是否开启会话缓存buffer决定将buffer数据进行压缩还是存储在会话中;如果在一次解码数据返回true,但buffer中没有数据,则从会话中移除属性BUFFER,并释放对应的buffer空间。doDecode方法放抽象方法待类型实现。CumulativeProtocolDecoder实现可累性方法主要是通过将buffer存储在会话中,以实现接收数据的可累计性。
发表评论
-
Mina 报文连接器(NioDatagramConnector)
2017-06-14 08:46 1336Mina 抽象Polling连接器(A ... -
Mina 报文监听器NioDatagramAcceptor二(发送会话消息等)
2017-06-13 16:01 1487Mina 报文监听器NioDatagramAcceptor一( ... -
Mina 报文监听器NioDatagramAcceptor一(初始化,Io处理器)
2017-06-13 09:51 2499Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina 报文通信简单示例
2017-06-12 09:01 2481MINA TCP简单通信实例:http://donald-dr ... -
Mina socket连接器(NioSocketConnector)
2017-06-12 08:37 4638Mina 抽象Polling连接器(AbstractPolli ... -
Mina 抽象Polling连接器(AbstractPollingIoConnector)
2017-06-11 21:29 958Mina 连接器接口定义及抽象实现(IoConnector ) ... -
Mina 连接器接口定义及抽象实现(IoConnector )
2017-06-11 13:46 1769Mina IoService接口定义及抽象实现:http:// ... -
Mina socket监听器(NioSocketAcceptor)
2017-06-09 08:44 3331Mina IoService接口定义及抽象实现:http:// ... -
Mina 抽象polling监听器
2017-06-08 22:32 707Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina Io监听器接口定义及抽象实现
2017-06-07 13:02 1293Mina IoService接口定义及抽象实现:http:// ... -
Mina IoService接口定义及抽象实现
2017-06-06 23:44 1122Mina IoHandler接口定义:http://donal ... -
Mina Nio会话(Socket,DataGram)
2017-06-06 12:53 1142Mina Socket会话配置:http://donald-d ... -
Mina 抽象Io会话
2017-06-05 22:45 966Mina Io会话接口定义:http://donald-dra ... -
Mina Io会话接口定义
2017-06-04 23:15 1093Mina Nio处理器:http://donald-drape ... -
Mina Nio处理器
2017-06-04 22:19 690Mina Io处理器抽象实现:http://donald-dr ... -
Mina Io处理器抽象实现
2017-06-03 23:52 1081Mina 过滤链抽象实现:http://donald-drap ... -
Mina IoHandler接口定义
2017-06-01 21:30 1668Mina 过滤链抽象实现:http://donald-drap ... -
MINA 多路复用协议编解码器工厂二(多路复用协议解码器)
2017-06-01 12:52 2191MINA 多路复用协议编解码器工厂一(多路复用协议编码器): ... -
MINA 多路复用协议编解码器工厂一(多路复用协议编码器)
2017-05-31 22:22 1790MINA 多路分离解码器实例:http://donald-dr ... -
Mina 协议编解码过滤器三(会话write与消息接收过滤)
2017-05-28 07:22 1688Mina 协议编解码过滤器一(协议编解码工厂、协议编码器): ...
相关推荐
许多刚接触mina的朋友,对于mina的编解码器的编写很迷惑.希望这个文档可以帮助朋友们少走弯路。 资源中是一个比较典型的编解码器写法。生成了可执行文件。并对编解码器的代码有详细注释。
NULL 博文链接:https://thb143.iteye.com/blog/1538083
NULL 博文链接:https://wen866595.iteye.com/blog/1154137
mina仿qq聊天功能,自定义协议,协议的编码和...mina聊天 mina解码编码 mina协议开发 mina仿qq mina消息xml mina开发的在线聊天工具,mina仿qq功能,mina自定义协议,可以仿http请求,mina心跳等技术大全,mina功能大揭密
公司需求,做的简单的Demo,可以拓展,Mina自定义协议简单实现,象征性得收取2积分
mina通信协议文档及实例,内含说明文档及实例,长短连接
mina 多路分离解码
该压缩包中有两个文件夹mina_server和minaclient,先启动mina_server,然后启动minaclient即可运行
mina 协议 解包 粘包
Mina自定义协议通信的示例
这个代码,在mina框架中,实现了编码解码,包含了服务器端发送数据的代码和作为客户端接收数据的代码。
使用MINA自带的心跳协议编写的心跳的Demo
mina自定义编解码 不错的资源 ----其实不怎么样,技术就是拿出来共享的,开源。大家一起前进
apache mina 框架 实例 自定义协议包 自定义编码器 解码器 服务端 客户端
NULL 博文链接:https://wchao226.iteye.com/blog/2246846
springboot 整合了mina 并自定义解码器 复制进去导个包即可食用
服务器框架MINA使用经验总结 socket协议通信框架
详细介绍mina框架的各个组成部分、服务器端的开发、客户端开发。并根据本人在工程项目中使用的代码,详细讲解了服务器端是客户端实现。实现了json格式的通信、以及文件的上传于下载等功能。图文并茂,以开发者的角度...
可用于快速开发SOCKET开发的软件包
有关mina TCP Server 及协议报文结构解码器