|  |  | 
 |  |  | import org.apache.logging.log4j.Logger; | 
 |  |  | import org.apache.mina.core.buffer.BufferDataException; | 
 |  |  | import org.apache.mina.core.buffer.IoBuffer; | 
 |  |  | import org.apache.mina.core.session.IoSession; | 
 |  |  |  | 
 |  |  |  | 
 |  |  | @AnnotationPrefixedDataAvailable( | 
 |  |  |       enable = true, | 
 |  |  |       protocolName = ProtocolConstantV206V2.protocolName, | 
 |  |  |       protocolVersion = ProtocolConstantV206V2.protocolVer, | 
 |  |  |       priority = ProtocolConstantV206V2.priority, | 
 |  |  |       onLineDataMinLength = ProtocolConstantV206V2.onLineDataMinLength, | 
 |  |  |       headMinLength = ProtocolConstantV206V2.headMinLength) | 
 |  |  | 
 |  |  |    private static final Logger log = LogManager.getLogger(PrefixedDataAvailableV2.class) ; | 
 |  |  |     | 
 |  |  |    private static final String protocolName = ProtocolConstantV206V2.protocolName ; | 
 |  |  |  | 
 |  |  |    private static final short protocolVersion = ProtocolConstantV206V2.protocolVer ; | 
 |  |  |  | 
 |  |  |    /** | 
 |  |  |     * 分析上线数据(网络连接后第一包数据)是否可获得 | 
 |  |  | 
 |  |  |     * @return 不是本协议数据时返回空 | 
 |  |  |     * @throws Exception 异常 | 
 |  |  |     */ | 
 |  |  |    public PrefixedDataAvailableStatus forOnLine(IoBuffer in,  | 
 |  |  |          int remain, | 
 |  |  |          int minDataLength, //对应ProtocolConstantV2_0.onLineDataMinLength | 
 |  |  |          int maxDataLength //对应ProtocolConstant.errorMaxLength | 
 |  |  |          ) throws Exception { | 
 |  |  |    public PrefixedDataAvailableStatus forOnLine(IoSession ioSession, | 
 |  |  |                                      IoBuffer in, | 
 |  |  |                                      int remain, | 
 |  |  |                                      int minDataLength, //对应ProtocolConstantV2_0.onLineDataMinLength | 
 |  |  |                                      int maxDataLength //对应ProtocolConstant.errorMaxLength | 
 |  |  |                                      ) throws Exception { | 
 |  |  |        | 
 |  |  |       int oldPosition = in.position() ; | 
 |  |  |       byte[] preByte = new byte[remain]; | 
 |  |  | 
 |  |  |       //in.position(0) ;//错误用法,如果发生粘包数据,将会死循环 | 
 |  |  |       in.position(oldPosition) ; | 
 |  |  |  | 
 |  |  |       return this.doForData(preByte, minDataLength, maxDataLength) ; | 
 |  |  |       return this.doForData(ioSession, preByte, minDataLength, maxDataLength) ; | 
 |  |  |    } | 
 |  |  |  | 
 |  |  |    /** | 
 |  |  | 
 |  |  |     * @throws Exception 异常 | 
 |  |  |     */ | 
 |  |  |    @Override | 
 |  |  |    public PrefixedDataAvailableStatus forUpData(IoBuffer in,  | 
 |  |  |          int remain, | 
 |  |  |          int minDataLength, | 
 |  |  |          int maxDataLength) throws Exception { | 
 |  |  |    public PrefixedDataAvailableStatus forUpData(IoSession ioSession, | 
 |  |  |                                      IoBuffer in, | 
 |  |  |                                      int remain, | 
 |  |  |                                      int minDataLength, | 
 |  |  |                                      int maxDataLength) throws Exception { | 
 |  |  |       int oldPosition = in.position() ; | 
 |  |  |       byte[] preByte = new byte[remain]; | 
 |  |  |       in.get(preByte) ; | 
 |  |  |       //in.position(0) ;//错误用法,如果发生粘包数据,将会死循环 | 
 |  |  |       in.position(oldPosition) ; | 
 |  |  |        | 
 |  |  |       return this.doForData(preByte, minDataLength, maxDataLength) ; | 
 |  |  |       return this.doForData(ioSession, preByte, minDataLength, maxDataLength) ; | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |    /** | 
 |  |  |     * 进行判断 | 
 |  |  |     * @param ioSession ioSession | 
 |  |  |     * @param preByte byte[] | 
 |  |  |     * @param minDataLength 最小数据长度 | 
 |  |  |     * @param maxDataLength 最大数据长度 | 
 |  |  |     * @return PrefixedDataAvailableStatus | 
 |  |  |     * @throws Exception 异常 | 
 |  |  |     */ | 
 |  |  |    private PrefixedDataAvailableStatus doForData(byte[] preByte, int minDataLength, int maxDataLength) throws Exception{ | 
 |  |  |    private PrefixedDataAvailableStatus doForData(IoSession ioSession, byte[] preByte, int minDataLength, int maxDataLength) throws Exception{ | 
 |  |  |       int remain = preByte.length ; | 
 |  |  |         | 
 |  |  |         if (remain < minDataLength) { | 
 |  |  |            log.warn("基于协议(" + protocolName + ")判断数据头部发生断包现象。") ; | 
 |  |  |            log.warn("基于协议(" + (protocolName + protocolVersion) + ")判断数据头部发生断包现象。") ; | 
 |  |  |             return new PrefixedDataAvailableStatus().breaked() ; | 
 |  |  |         } | 
 |  |  |          | 
 |  |  | 
 |  |  |          return new PrefixedDataAvailableStatus().rubbish(remain) ; | 
 |  |  |       } | 
 |  |  |  | 
 |  |  | 		 | 
 |  |  |         CommonV2 parseCommon = new CommonV2(); | 
 |  |  |       boolean isThisProtocolData = parseCommon.isThisProtocolHead(preByte) ; | 
 |  |  |  | 
 |  |  |       if(!isThisProtocolData){ | 
 |  |  |       Boolean[] isThisProtocolData = parseCommon.isThisProtocolHead(preByte) ; | 
 |  |  |       if(isThisProtocolData == null || isThisProtocolData.length != 2 || !isThisProtocolData[0].booleanValue()){ | 
 |  |  |          //不是本协议数据 | 
 |  |  |          return null ; | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |       Integer dataLen = parseCommon.parseFrameLen(preByte) ; | 
 |  |  |       Integer dataLen = parseCommon.parseFrameLen(preByte, isThisProtocolData[1]) ; | 
 |  |  |  | 
 |  |  |       if(dataLen == null){ | 
 |  |  |          String headHex = ByteUtil.bytes2Hex(preByte, true) ; | 
 |  |  | 
 |  |  |          | 
 |  |  |         if(remain == dataLen){ | 
 |  |  |            //不断不粘 | 
 |  |  |             return new PrefixedDataAvailableStatus().completed(dataLen) ; | 
 |  |  |             return new PrefixedDataAvailableStatus().completed(dataLen, protocolName, protocolVersion) ; | 
 |  |  |         }else if(remain > dataLen){ | 
 |  |  |          String headHex = ByteUtil.bytes2Hex(preByte, true) ; | 
 |  |  |            log.warn("收到数据之帧前部:" + headHex + ",但发生粘包现象。") ; | 
 |  |  |             return new PrefixedDataAvailableStatus().adjoined(dataLen) ; | 
 |  |  |             return new PrefixedDataAvailableStatus().adjoined(dataLen, protocolName, protocolVersion) ; | 
 |  |  |         }else{ | 
 |  |  |            // remain < dataLen | 
 |  |  |          String headHex = ByteUtil.bytes2Hex(preByte, true) ; |