ModbusTcpDelimiterHandler.java 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package wei.yigulu.modbus.netty;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import org.joda.time.DateTime;
  5. import wei.yigulu.netty.AbstractDelimiterHandler;
  6. /**
  7. * 未继承netty的数据帧处理拆包类
  8. *
  9. * @author 修唯xiuwei
  10. * @version 3.0
  11. */
  12. public class ModbusTcpDelimiterHandler extends AbstractDelimiterHandler {
  13. /**
  14. * 最短帧为错误帧 9为 4位事务+2位长度+1位slaveID+1位functionCode+1位exceptionCode
  15. */
  16. private static final int MINLENGTH = 9;
  17. @Override
  18. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  19. //log.warn("接收到原始的报文 :"+ DataConvertor.ByteBuf2String((ByteBuf) msg));
  20. if (isOverMaxLength((ByteBuf) msg)) {
  21. return;
  22. }
  23. //数据帧长度不足 记录时间 等待下一帧进入
  24. int length;
  25. while (cumulation.readableBytes() >= MINLENGTH) {
  26. cumulation.markReaderIndex();
  27. //去掉四位事务帧
  28. cumulation.readBytes(4).release();
  29. length = cumulation.readUnsignedShort();
  30. if (length > 255 || length < 3) {
  31. log.warn("不是正常的长度,该帧疑似异常帧,舍弃");
  32. clearCumulation();
  33. return;
  34. }
  35. if (length > cumulation.readableBytes()) {
  36. log.debug("数据帧长度不足进入等待 预计长度:" + length + ",实际长度:" + cumulation.readableBytes());
  37. timeMark = DateTime.now();
  38. cumulation.resetReaderIndex();
  39. return;
  40. } else {
  41. cumulation.resetReaderIndex();
  42. ctx.fireChannelRead(cumulation.readBytes(length + 6));
  43. }
  44. }
  45. if (cumulation.readableBytes() != 0) {
  46. this.timeMark = DateTime.now();
  47. } else {
  48. clearCumulation();
  49. }
  50. }
  51. }