1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- package wei.yigulu.iec104.nettyconfig;
- import io.netty.buffer.ByteBuf;
- import io.netty.buffer.ByteBufUtil;
- import io.netty.channel.ChannelHandlerContext;
- import org.joda.time.DateTime;
- import wei.yigulu.netty.AbstractDelimiterHandler;
- import wei.yigulu.utils.DataConvertor;
- import java.util.HashMap;
- /**
- * 未继承netty的数据帧处理拆包类
- *
- * @author 修唯xiuwei
- * @version 3.0
- */
- public class AllCustomDelimiterHandler extends AbstractDelimiterHandler {
- private static final byte[] HEAD = new byte[]{0x68};
- public AllCustomDelimiterHandler(){
- this.maxTimeSpace=100;
- this.maxLength=10240;
- }
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- if(isOverMaxLength((ByteBuf) msg)){
- return;
- }
- int len;
- //查看第一个 HEAD 的头位置
- int headIndex = getHeadIndex(0, cumulation.writerIndex(), cumulation, HEAD);
- //当数据帧里存在头字节 且长度大于3时进入循环
- while (cumulation.readableBytes() >= 6 && headIndex != -1) {
- //如果头字节不在第一个字节 那么读取标志向后推到头字节位置
- if (headIndex > cumulation.readerIndex()) {
- log.warn("舍弃了一无用段报文:" + DataConvertor.ByteBuf2StringAndRelease(cumulation.readBytes(headIndex - cumulation.readerIndex())));
- }
- //标记读取位置
- cumulation.markReaderIndex();
- //向后读取一位 即0x68的占位
- cumulation.readBytes(1).release();
- //获取到该帧的长度 帧内标定的长度
- len = cumulation.readUnsignedByte();
- //如果帧的真实长度少于 帧内标定长度则代表数据帧不完整,退出循环等待下一数据帧进入进行粘帧
- if (cumulation.readableBytes() < len) {
- cumulation.resetReaderIndex();
- //数据帧长度不足 记录时间
- timeMark = DateTime.now();
- return;
- } else {
- cumulation.resetReaderIndex();
- //如果数据帧长度足够 将规定长度的直接加入out 队列
- ctx.fireChannelRead(cumulation.readBytes(len + 2));
- //查看后续的字节里面头字节的位置
- headIndex = getHeadIndex(cumulation.readerIndex(), cumulation.writerIndex(), cumulation,HEAD);
- }
- }
- if (cumulation.readableBytes() != 0 && headIndex >= cumulation.readerIndex()) {
- //buffer中还有数据 而且其中有数据头
- timeMark = DateTime.now();
- return;
- } else {
- //buffer没有数据 或剩余这段字节中没有数据头
- if (cumulation.readableBytes() != 0) {
- log.warn("这段字节中没有数据头,舍弃:" + DataConvertor.ByteBuf2String(cumulation.readBytes(cumulation.readableBytes())));
- }
- clearCumulation();
- }
- }
- }
|