AllCustomDelimiterHandler.java 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package wei.yigulu.iec104.nettyconfig;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.buffer.ByteBufUtil;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import org.joda.time.DateTime;
  6. import wei.yigulu.netty.AbstractDelimiterHandler;
  7. import wei.yigulu.utils.DataConvertor;
  8. import java.util.HashMap;
  9. /**
  10. * 未继承netty的数据帧处理拆包类
  11. *
  12. * @author 修唯xiuwei
  13. * @version 3.0
  14. */
  15. public class AllCustomDelimiterHandler extends AbstractDelimiterHandler {
  16. private static final byte[] HEAD = new byte[]{0x68};
  17. public AllCustomDelimiterHandler(){
  18. this.maxTimeSpace=100;
  19. this.maxLength=10240;
  20. }
  21. @Override
  22. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  23. if(isOverMaxLength((ByteBuf) msg)){
  24. return;
  25. }
  26. int len;
  27. //查看第一个 HEAD 的头位置
  28. int headIndex = getHeadIndex(0, cumulation.writerIndex(), cumulation, HEAD);
  29. //当数据帧里存在头字节 且长度大于3时进入循环
  30. while (cumulation.readableBytes() >= 6 && headIndex != -1) {
  31. //如果头字节不在第一个字节 那么读取标志向后推到头字节位置
  32. if (headIndex > cumulation.readerIndex()) {
  33. log.warn("舍弃了一无用段报文:" + DataConvertor.ByteBuf2StringAndRelease(cumulation.readBytes(headIndex - cumulation.readerIndex())));
  34. }
  35. //标记读取位置
  36. cumulation.markReaderIndex();
  37. //向后读取一位 即0x68的占位
  38. cumulation.readBytes(1).release();
  39. //获取到该帧的长度 帧内标定的长度
  40. len = cumulation.readUnsignedByte();
  41. //如果帧的真实长度少于 帧内标定长度则代表数据帧不完整,退出循环等待下一数据帧进入进行粘帧
  42. if (cumulation.readableBytes() < len) {
  43. cumulation.resetReaderIndex();
  44. //数据帧长度不足 记录时间
  45. timeMark = DateTime.now();
  46. return;
  47. } else {
  48. cumulation.resetReaderIndex();
  49. //如果数据帧长度足够 将规定长度的直接加入out 队列
  50. ctx.fireChannelRead(cumulation.readBytes(len + 2));
  51. //查看后续的字节里面头字节的位置
  52. headIndex = getHeadIndex(cumulation.readerIndex(), cumulation.writerIndex(), cumulation,HEAD);
  53. }
  54. }
  55. if (cumulation.readableBytes() != 0 && headIndex >= cumulation.readerIndex()) {
  56. //buffer中还有数据 而且其中有数据头
  57. timeMark = DateTime.now();
  58. return;
  59. } else {
  60. //buffer没有数据 或剩余这段字节中没有数据头
  61. if (cumulation.readableBytes() != 0) {
  62. log.warn("这段字节中没有数据头,舍弃:" + DataConvertor.ByteBuf2String(cumulation.readBytes(cumulation.readableBytes())));
  63. }
  64. clearCumulation();
  65. }
  66. }
  67. }