ModbusRtuMasterDelimiterHandler.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package wei.yigulu.modbus.netty;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import lombok.Getter;
  5. import lombok.Setter;
  6. import lombok.experimental.Accessors;
  7. import org.joda.time.DateTime;
  8. import wei.yigulu.modbus.domain.datatype.numeric.P_BA;
  9. import wei.yigulu.netty.AbstractDelimiterHandler;
  10. import wei.yigulu.utils.CrcUtils;
  11. import wei.yigulu.utils.DataConvertor;
  12. /**
  13. * 未继承netty的数据帧处理拆包类
  14. *
  15. * @author 修唯xiuwei
  16. * @version 3.0
  17. */
  18. public class ModbusRtuMasterDelimiterHandler extends AbstractDelimiterHandler {
  19. @Setter
  20. @Accessors(chain = true)
  21. /**
  22. * 是否进行CRC校验判断
  23. */
  24. private boolean doCrcCheck = true;
  25. /**
  26. * 判断是否是断包的最大时间间隔
  27. */
  28. @Setter
  29. @Getter
  30. @Accessors(chain = true)
  31. protected int maxTimeSpace=1000;
  32. @Override
  33. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  34. log.info("接收到原始的报文 :"+ DataConvertor.ByteBuf2String((ByteBuf) msg));
  35. if (isOverMaxLength((ByteBuf) msg)) {
  36. return;
  37. }
  38. //原crc值
  39. int crcO;
  40. //理论crc值
  41. int crcS;
  42. byte[] bs;
  43. int byteNum;
  44. int functionCode;
  45. while (cumulation.readableBytes() >= 5) {
  46. cumulation.markReaderIndex();
  47. cumulation.readBytes(1).release();
  48. functionCode = cumulation.readUnsignedByte();
  49. if (functionCode > 0x80 ) {
  50. //异常功能码 异常帧
  51. byteNum = 0;
  52. } else {
  53. byteNum = cumulation.readUnsignedByte();
  54. }
  55. if (byteNum < 0 || byteNum > 250) {
  56. cumulation.resetReaderIndex();
  57. log.error("该帧字节长度不在规定范围内,整帧舍弃:" + DataConvertor.ByteBuf2String(cumulation.readBytes(cumulation.readableBytes())));
  58. clearCumulation();
  59. return;
  60. }
  61. if (this.doCrcCheck) {
  62. bs = new byte[byteNum + 3];
  63. cumulation.resetReaderIndex();
  64. if (cumulation.readableBytes() < byteNum + 5) {
  65. break;
  66. }
  67. cumulation.readBytes(bs);
  68. crcO = cumulation.readUnsignedShortLE();
  69. crcS = CrcUtils.generateCRC16(bs).intValue();
  70. if (crcO == crcS) {
  71. cumulation.resetReaderIndex();
  72. ctx.fireChannelRead(cumulation.readBytes(byteNum + 5));
  73. } else {
  74. cumulation.resetReaderIndex();
  75. log.warn("数据帧crc校验错误,舍弃:" + DataConvertor.ByteBuf2String(cumulation) + "原CRC:" + DataConvertor.Byte2String(P_BA.decode(crcO)) + "理论CRC:" + DataConvertor.Byte2String(P_BA.decode(crcS)));
  76. clearCumulation();
  77. return;
  78. }
  79. } else {
  80. cumulation.resetReaderIndex();
  81. ctx.fireChannelRead(cumulation.readBytes(byteNum + 5));
  82. }
  83. }
  84. if (cumulation.readableBytes() == 0) {
  85. clearCumulation();
  86. }else{
  87. timeMark = DateTime.now();
  88. }
  89. }
  90. }