예제 #1
0
        /// <summary>
        /// Parse
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="buffer"></param>
        /// <param name="readlength"></param>
        /// <returns></returns>
        /// <exception cref="BadProtocolException"></exception>
        public ZookResponse Parse(IConnection connection, ArraySegment <byte> buffer, out int readlength)
        {
            if (buffer.Count < 4)
            {
                readlength = 0;
                return(null);
            }

            var payload = buffer.Array;

            //获取message length
            var messageLength = NetworkBitConverter.ToInt32(payload, buffer.Offset);

            readlength = messageLength + 4;
            if (buffer.Count < readlength)
            {
                readlength = 0;
                return(null);
            }

            //首次connect to zk response
            var connectRequest = connection.UserData as Request <ZookResponse>;

            if (connectRequest != null)
            {
                connection.UserData = null;
                var connectResponseBuffer = new byte[messageLength];
                Buffer.BlockCopy(payload, buffer.Offset + 4, connectResponseBuffer, 0, messageLength);
                return(new ZookResponse(connectRequest.SeqID, connectResponseBuffer));
            }

            var xid  = NetworkBitConverter.ToInt32(payload, buffer.Offset + 4);
            var zxid = NetworkBitConverter.ToInt64(payload, buffer.Offset + 8);
            var err  = NetworkBitConverter.ToInt32(payload, buffer.Offset + 16);

            var bodylength = messageLength - 16;

            if (bodylength < 0)
            {
                throw new BadProtocolException("illegality message length.");
            }

            byte[] bodyBytes = null;
            if (bodylength > 0)
            {
                bodyBytes = new byte[bodylength];
                Buffer.BlockCopy(payload, buffer.Offset + 20, bodyBytes, 0, bodyBytes.Length);
            }
            return(new ZookResponse(xid, zxid, (Data.ZoookError)err, bodyBytes));
        }
예제 #2
0
        /// <summary>
        /// 将客户端转来的byte[]转换成指定对象(自定义协议)
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="buffer"></param>
        /// <param name="maxMessageSize"></param>
        /// <param name="readlength"></param>
        /// <returns></returns>
        /// <exception cref="BadProtocolException">bad async binary protocl</exception>
        public DSSBinaryCommandInfo FindCommandInfo(IConnection connection, ArraySegment <byte> buffer,
                                                    int maxMessageSize, out int readlength)
        {
            if (buffer.Count < 4)
            {
                readlength = 0; return(null);
            }

            var payload = buffer.Array;

            //获取message length
            var messageLength = NetworkBitConverter.ToInt32(payload, buffer.Offset);

            if (messageLength < 7)
            {
                throw new BadProtocolException("bad async binary protocl");
            }
            if (messageLength > maxMessageSize)
            {
                throw new BadProtocolException("message is too long");
            }

            readlength = messageLength + 4;
            if (buffer.Count < readlength)
            {
                readlength = 0; return(null);
            }

            var seqID               = NetworkBitConverter.ToInt32(payload, buffer.Offset + 4);
            var projectID           = NetworkBitConverter.ToInt16(payload, buffer.Offset + 8);
            var extProperty         = NetworkBitConverter.ToInt16(payload, buffer.Offset + 10);
            var cmdNameLength       = NetworkBitConverter.ToInt16(payload, buffer.Offset + 12);
            var versionNumberLength = NetworkBitConverter.ToInt16(payload, buffer.Offset + 14);
            var projectNameLength   = NetworkBitConverter.ToInt16(payload, buffer.Offset + 16);
            var strName             = Encoding.UTF8.GetString(payload, buffer.Offset + 18, cmdNameLength);
            var versionNumber       = Encoding.UTF8.GetString(payload, buffer.Offset + 18 + cmdNameLength, versionNumberLength);
            var projectName         = Encoding.UTF8.GetString(payload, buffer.Offset + 18 + cmdNameLength + versionNumberLength, projectNameLength);
            var dataLength          = messageLength - 12 - cmdNameLength - versionNumberLength - projectNameLength;

            byte[] data = null;
            if (dataLength > 0)
            {
                data = new byte[dataLength];
                Buffer.BlockCopy(payload, buffer.Offset + 18 + cmdNameLength + versionNumberLength + projectNameLength, data, 0, dataLength);
            }
            return(new DSSBinaryCommandInfo(seqID, projectID, projectName, extProperty, strName, versionNumber, data));
        }
예제 #3
0
        object IDecoder.decode(IConnection connection, byte[] buffer)
        {
            try
            {
                int namelen = NetworkBitConverter.ToInt32(buffer, 0);

                string name = Encoding.Default.GetString(buffer, 4, namelen);

                int age = NetworkBitConverter.ToInt32(buffer, 4 + namelen);

                return(new UserInfo(name, age));
            }
            catch (Exception)
            {
                return(new UserInfo("error", 0));
            }
        }
예제 #4
0
        /// <summary>
        /// find response
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="buffer"></param>
        /// <param name="readlength"></param>
        /// <returns></returns>
        /// <exception cref="BadProtocolException">bad async binary protocl</exception>
        public DSSBinaryResponse FindResponse(IConnection connection, ArraySegment <byte> buffer, out int readlength)
        {
            if (buffer.Count < 4)
            {
                readlength = 0; return(null);
            }

            //获取message length
            var messageLength = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset);

            if (messageLength < 7)
            {
                throw new BadProtocolException("bad async binary protocl");
            }

            readlength = messageLength + 4;
            if (buffer.Count < readlength)
            {
                readlength = 0; return(null);
            }

            var seqID             = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset + 4);
            var projectID         = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 8);
            var extProperty       = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 10);
            var flagLength        = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 12);
            var versonLength      = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 14);
            var projectNameLength = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 16);
            var strName           = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + 18, flagLength);
            var versionNumber     = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + 18 + flagLength, versonLength);
            var projectName       = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + 18 + flagLength + versonLength, projectNameLength);
            var dataLength        = messageLength - 16 - flagLength - versonLength - projectNameLength;

            byte[] data = null;
            if (dataLength > 0)
            {
                data = new byte[dataLength];
                Buffer.BlockCopy(buffer.Array, buffer.Offset + 18 + flagLength + versonLength + projectNameLength, data, 0, dataLength);
            }
            return(new DSSBinaryResponse(seqID, projectID, projectName, extProperty, strName, versionNumber, data));
        }
예제 #5
0
        /// <summary>
        /// 解析头部
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="datas"></param>
        /// <param name="count"></param>
        /// <param name="giveupCount"></param>
        /// <returns></returns>
        protected unsafe override bool ParseHeader(Packet _packet, ArraySegment <byte> datas)
        {
            InnerTunnelPacket packet = _packet as InnerTunnelPacket;

            if (packet == null)
            {
                return(false);
            }


            if (datas.Array[datas.Offset] != 0x0d || datas.Array[datas.Offset + 1] != 0x0a)
            {
                return(false);
            }

            packet.ContentLength = NetworkBitConverter.ToInt32(
                datas.Array[datas.Offset + 2],
                datas.Array[datas.Offset + 3],
                datas.Array[datas.Offset + 4],
                datas.Array[datas.Offset + 5]);

            packet.Action         = datas.Array[datas.Offset + 6];
            packet.ClientIdentity = NetworkBitConverter.ToInt64(
                datas.Array[datas.Offset + 7],
                datas.Array[datas.Offset + 8],
                datas.Array[datas.Offset + 9],
                datas.Array[datas.Offset + 10],
                datas.Array[datas.Offset + 11],
                datas.Array[datas.Offset + 12],
                datas.Array[datas.Offset + 13],
                datas.Array[datas.Offset + 14]);

            packet.ServicePort = NetworkBitConverter.ToInt32(
                datas.Array[datas.Offset + 15],
                datas.Array[datas.Offset + 16],
                datas.Array[datas.Offset + 17],
                datas.Array[datas.Offset + 18]);
            return(true);
        }
예제 #6
0
        /// <summary>
        /// 解析头部
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="datas"></param>
        /// <param name="count"></param>
        /// <param name="giveupCount"></param>
        /// <returns></returns>
        protected override bool ParseHeader(Packet _packet, ArraySegment <byte> datas)
        {
            ZTProtocolPacket packet = _packet as ZTProtocolPacket;

            if (packet == null)
            {
                return(false);
            }


            if (datas.Array[datas.Offset] != 0x0d || datas.Array[datas.Offset + 1] != 0x0a)
            {
                return(false);
            }

            packet.ContentLength = NetworkBitConverter.ToInt32(
                datas.Array[datas.Offset + 2],
                datas.Array[datas.Offset + 3],
                datas.Array[datas.Offset + 4],
                datas.Array[datas.Offset + 5]);
            return(true);
        }
예제 #7
0
        private async Task <MessageHeader> ReadHeader(CancellationToken ct = default)
        {
            byte[] headerBuffer    = null;
            byte[] timestampBuffer = null;
            try
            {
                headerBuffer    = _arrayPool.Rent(15);
                timestampBuffer = _arrayPool.Rent(4);
                await _stream.ReadBytesAsync(headerBuffer.AsMemory(0, 15), ct);

                var type   = (MessageType)headerBuffer[4];
                var length = NetworkBitConverter.ToUInt24(headerBuffer.AsSpan(5, 3));

                headerBuffer.AsSpan(8, 3).CopyTo(timestampBuffer.AsSpan(1));
                timestampBuffer[0] = headerBuffer[11];
                var timestamp = NetworkBitConverter.ToInt32(timestampBuffer.AsSpan(0, 4));
                var streamId  = NetworkBitConverter.ToUInt24(headerBuffer.AsSpan(12, 3));
                var header    = new MessageHeader()
                {
                    MessageLength   = length,
                    MessageStreamId = streamId,
                    MessageType     = type,
                    Timestamp       = (uint)timestamp
                };
                return(header);
            }
            finally
            {
                if (headerBuffer != null)
                {
                    _arrayPool.Return(headerBuffer);
                }
                if (timestampBuffer != null)
                {
                    _arrayPool.Return(timestampBuffer);
                }
            }
        }
예제 #8
0
 /// <summary>
 /// 通信长度,不包含协议头的长度
 /// </summary>
 /// <param name="datas"></param>
 /// <returns></returns>
 public virtual int GetSize(byte[] datas)
 {
     return(NetworkBitConverter.ToInt32(datas, 2));
 }
예제 #9
0
        /// <summary>
        /// find response
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="buffer"></param>
        /// <param name="readlength"></param>
        /// <returns></returns>
        public RiakResponse Parse(IConnection connection, ArraySegment <byte> buffer, out int readlength)
        {
            //riak协议长度至少5字节(len+mc)
            if (buffer.Count < 5)
            {
                readlength = 0;
                return(null);
            }

            //riak协议编码为big-endian
            var len = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset);

            if (len < 1)
            {
                throw new BadProtocolException();
            }

            //riak协议长度=message code(1 byte)+Message(N bytes)
            readlength = len + 4;
            //判断本次接收数据是否完整
            if (readlength > buffer.Count)
            {
                readlength = 0;
                return(null);
            }

            var response = connection.UserData as RiakResponse;

            if (response == null)
            {
                throw new BadProtocolException("unknow response.");
            }

            //第5个字节为MessageCode
            var messageCode = buffer.Array[buffer.Offset + 4];

            //riak error response
            if (messageCode == Messages.Codes.ErrorResp)
            {
                Messages.RpbErrorResp errResp = null;
                using (var stream = new MemoryStream(buffer.Array, buffer.Offset + 5, len - 1))
                    errResp = ProtoBuf.Serializer.Deserialize <Messages.RpbErrorResp>(stream);

                response.Exception = new RiakException(errResp.errcode, Encoding.UTF8.GetString(errResp.errmsg));
                return(response);
            }

            //message code mismatching
            if (messageCode != response.MessageCode)
            {
                response.Exception = new RiakException(string.Concat(
                                                           "invalid response, expected is ", response.MessageCode.ToString(), ", but was is ", messageCode.ToString()));
                return(response);
            }

            if (len == 1)
            {
                return(response);
            }
            if (response.OnReceive(new ArraySegment <byte>(buffer.Array, buffer.Offset + 5, len - 1)))
            {
                return(response);
            }
            return(null);
        }
예제 #10
0
        public override void Deserialize(SerializationContext context)
        {
            var chunkSize = NetworkBitConverter.ToInt32(context.ReadBuffer.Span);

            ChunkSize = (uint)chunkSize;
        }