/// <summary> /// 将字节数组解析出ssl record layer格式。V3_3 /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static bool GetRecordLayerNetMQMessage(this byte[] bytes, ref bool changeCipherSpec, ref int offset, out List <NetMQMessage> sslMessages) { //用一个临时遍历保存偏移量,只有这个当前解析成功才偏移。 int tempOffset = offset; if (bytes.Length - tempOffset < 5) { //长度至少要有5位 //ContentType (1,handshake:22) //ProtocolVersion(2) //握手协议长度:(2) //握手协议数据 sslMessages = null; return(false); } NetMQMessage sslMessage = new NetMQMessage(); byte[] contentTypeBytes = new byte[Constants.CONTENT_TYPE_LENGTH]; //get content type Buffer.BlockCopy(bytes, tempOffset, contentTypeBytes, 0, Constants.CONTENT_TYPE_LENGTH); tempOffset += Constants.CONTENT_TYPE_LENGTH; byte[] protocolVersionBytes = new byte[Constants.PROTOCOL_VERSION_LENGTH]; //get protocol version Buffer.BlockCopy(bytes, tempOffset, protocolVersionBytes, 0, Constants.PROTOCOL_VERSION_LENGTH); tempOffset += Constants.PROTOCOL_VERSION_LENGTH; byte[] handshakeLengthBytes = new byte[Constants.HAND_SHAKE_LENGTH]; //get hand shake layer //0012->1200->2100 Buffer.BlockCopy(bytes, tempOffset, handshakeLengthBytes, 0, Constants.HAND_SHAKE_LENGTH); tempOffset += Constants.HAND_SHAKE_LENGTH; //交换2个字节位置。 byte[] temp = new byte[2]; temp[1] = handshakeLengthBytes[0]; temp[0] = handshakeLengthBytes[1]; //由于生成长度是BitConverter.GetBytes是Little-Endian,因此需要转换为Big-Endian。 //在解析长度时需要转回来。 //一定要4位才行 int length = BitConverter.ToUInt16(temp, 0); //解析handshake长度 if (tempOffset + length > bytes.Length) { sslMessages = null; //接收到的数据长度不够,可能发送拆包。等后续包过来。 return(false); } sslMessage.Append(contentTypeBytes); sslMessage.Append(protocolVersionBytes); sslMessage.Append(handshakeLengthBytes); //解析handShakeLayer或applicationdata sslMessages = GetRecordLayers((ContentType)contentTypeBytes[0], bytes, tempOffset, tempOffset + length, ref changeCipherSpec); tempOffset += length; offset = tempOffset; foreach (NetMQMessage record in sslMessages) { //每个record都添加头部 foreach (NetMQFrame head in sslMessage.Reverse())//倒置,先插入后面的。 { record.Push(head.Buffer); } } return(true); }