Exemplo n.º 1
0
        /// <summary>
        /// 生成Post得到的表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>
        private static void GeneratePostFormAndFiles(HttpRequest request, ReceiveStream buffer)
        {
            var boundary = default(string);

            if (request.IsApplicationFormRequest() == true)
            {
                HttpRequest.GenerateApplicationForm(request);
            }
            else if (request.IsMultipartFormRequest(out boundary) == true)
            {
                if (request.InputStrem.Length >= boundary.Length)
                {
                    HttpRequest.GenerateMultipartFormAndFiles(request, buffer, boundary);
                }
            }


            if (request.Form == null)
            {
                request.Form = new HttpNameValueCollection();
            }

            if (request.Files == null)
            {
                request.Files = new HttpFile[0];
            }
        }
Exemplo n.º 2
0
        public ServerDataMsg OnWorldData(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);
            ServerDataMsg msg = VRage.Serialization.MySerializer.CreateAndRead <ServerDataMsg>(ReceiveStream);

            return(msg);
        }
Exemplo n.º 3
0
        public void ToFile(string fileName)
        {
            FileStream fs;
            string     pathName = fileName;

#if !NETCORE
            if (HttpContext.Current != null)
#endif
            if (fileName.IndexOfAny(new char[] { '\\', ':' }) == -1)
            {
                pathName = Path.Combine(GxContext.StaticPhysicalPath(), fileName);
            }
#pragma warning disable SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}'
            using (fs = new FileStream(pathName, FileMode.Create, FileAccess.Write))
#pragma warning restore SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}'
            {
                ReceiveStream.Seek(0, SeekOrigin.Begin);
                Byte[] Buffer    = new Byte[1024];
                int    BytesRead = ReceiveStream.Read(Buffer, 0, 1024);
                while (BytesRead > 0)
                {
                    fs.Write(Buffer, 0, BytesRead);
                    BytesRead = ReceiveStream.Read(Buffer, 0, 1024);
                }
                ReceiveStream.Seek(0, SeekOrigin.Begin);
            }
        }
Exemplo n.º 4
0
        public ChatMsg OnChatMessage(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);
            ChatMsg msg = VRage.Serialization.MySerializer.CreateAndRead <ChatMsg>(ReceiveStream);

            return(msg);
        }
Exemplo n.º 5
0
 public void WriteFileReceive(byte[] data)
 {
     // write all bytes to file
     FileBytesReceived += data.Length;
     ReceiveStream.Write(data, 0, data.Length);
     ReceiveStream.Flush();
 }
Exemplo n.º 6
0
        public ConnectedClientDataMsg OnClientConnected(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);
            ConnectedClientDataMsg msg = VRage.Serialization.MySerializer.CreateAndRead <ConnectedClientDataMsg>(ReceiveStream);

            return(msg);
        }
Exemplo n.º 7
0
        public JoinResultMsg OnJoinResult(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);
            JoinResultMsg msg = VRage.Serialization.MySerializer.CreateAndRead <JoinResultMsg>(ReceiveStream);

            return(msg);
        }
Exemplo n.º 8
0
        public void Dispose()
        {
            ReceiveStream?.Dispose();
            SendStream?.Dispose();

            _socket?.Dispose();
        }
Exemplo n.º 9
0
        public void ProcessReplicationCreate(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);

            TypeId    typeId     = ReceiveStream.ReadTypeId();
            NetworkId networkID  = ReceiveStream.ReadNetworkId();
            byte      groupCount = ReceiveStream.ReadByte();

            var pendingReplicable = new MyPendingReplicable();

            for (int i = 0; i < groupCount; i++)
            {
                var id = ReceiveStream.ReadNetworkId();
                pendingReplicable.StateGroupIds.Add(id);
            }

            Type          type       = GetTypeByTypeId(typeId);
            IMyReplicable replicable = (IMyReplicable)Activator.CreateInstance(type);

            pendingReplicable.DebugObject = replicable;
            pendingReplicable.IsStreaming = false;

            m_pendingReplicables.Add(networkID, pendingReplicable);

            replicable.OnLoad(ReceiveStream, (loaded) => SetReplicableReady(networkID, replicable, loaded));
        }
Exemplo n.º 10
0
            public void Dispose()
            {
                RawReceiveStream?.Dispose();
                SendStream?.Dispose();
                ReceiveStream?.Dispose();

                _webSocket?.Dispose();
            }
Exemplo n.º 11
0
        private ReceiveStream CreateStream(byte[] data)
        {
            var stream = new ReceiveStream(receiver);

            stream.Add(data);

            return(stream);
        }
Exemplo n.º 12
0
        public void ClearTest()
        {
            ReceiveStream target = new ReceiveStream(); // TODO: 初始化为适当的值

            target.Write(new byte[] { 1, 2 }, 0, 2);
            target.Clear();
            Assert.IsTrue(target.Length == 0);
        }
Exemplo n.º 13
0
        private ReceiveStream CreateStream(byte[] data)
        {
            var executorPacketReceiver = new ExecutorPacketReceiver(executor);
            var stream = new ReceiveStream(executorPacketReceiver);

            stream.Add(data);

            return(stream);
        }
Exemplo n.º 14
0
        /// <summary>
        /// 解析请求帧
        /// </summary>
        /// <param name="buffer">接收到的历史数据</param>
        /// <returns></returns>
        private IEnumerable <FrameRequest> GetFrameRequestsFromBuffer(ReceiveStream buffer)
        {
            FrameRequest request;

            while ((request = FrameRequest.From(buffer)) != null)
            {
                yield return(request);
            }
        }
Exemplo n.º 15
0
        public void ProcessReplicationDestroy(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);
            NetworkId networkID = ReceiveStream.ReadNetworkId();

            MyPendingReplicable pendingReplicable;

            if (!m_pendingReplicables.TryGetValue(networkID, out pendingReplicable)) // When it wasn't in pending replicables, it's already active and in scene, destroy it
            {
                IMyReplicable replicable = GetObjectByNetworkId(networkID) as IMyReplicable;
                // Debug.Assert(replicable != null, "Client received ReplicationDestroy, but object no longer exists (removed locally?)");
                if (replicable != null)
                {
                    using (m_tmpGroups)
                    {
                        var streamable = replicable as IMyStreamableReplicable;
                        if (streamable != null && streamable.NeedsToBeStreamed)
                        {
                            m_tmpGroups.Add(streamable.GetStreamingStateGroup());
                        }

                        replicable.GetStateGroups(m_tmpGroups);

                        foreach (var g in m_tmpGroups)
                        {
                            if (g == null)
                            {
                                continue;
                            }

                            if (g != replicable)
                            {
                                RemoveNetworkedObject(g);
                            }
                            g.Destroy();
                        }
                    }

                    RemoveNetworkedObject(replicable);
                    replicable.OnDestroy();
                }
            }
            else
            {
                m_pendingReplicables.Remove(networkID);
                if (pendingReplicable.IsStreaming)
                {
                    IMyStateGroup group = (IMyStateGroup)GetObjectByNetworkId(pendingReplicable.StreamingGroupId);
                    if (group != null)
                    {
                        RemoveNetworkedObject(group);
                        group.Destroy();
                    }
                }
                m_eventBuffer.RemoveEvents(networkID);
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="buffer">接收到的历史数据</param>
        private void ProcessRequest(T session, ReceiveStream buffer)
        {
            var requests = this.GetFrameRequestsFromBuffer(buffer);

            foreach (var request in requests)
            {
                // 新线程处理业务内容
                Task.Factory.StartNew(() => this.OnRecvRequest(session, request));
            }
        }
Exemplo n.º 17
0
        public void ClearTest1()
        {
            ReceiveStream target = new ReceiveStream(); // TODO: 初始化为适当的值

            target.Write(new byte[] { 1, 2 }, 0, 2);
            int count = 1; // TODO: 初始化为适当的值

            target.Clear(count);
            Assert.IsTrue(target.Length == 1 && target[0] == 2);
        }
Exemplo n.º 18
0
        public StreamHandler(object self, CommandDefinitions definitions, ILog log)
        {
            var target = new CommandExecutor(self, log);

            foreach (var definition in definitions.Definitions)
            {
                target.Define(definition.Key, definition.Value);
            }
            receiver      = new ExecutorPacketReceiver(target, log);
            receiveStream = new ReceiveStream(receiver, log);
        }
Exemplo n.º 19
0
        public void Dispose()
        {
            SendStream?.Dispose();
            SendStream = null;

            ReceiveStream?.Dispose();
            ReceiveStream = null;

            _socket?.Dispose();
            _socket = null;
        }
Exemplo n.º 20
0
        public void ItemTest()
        {
            ReceiveStream target = new ReceiveStream(); // TODO: 初始化为适当的值

            target.Write(new byte[] { 234 }, 0, 1);
            int  index = 0; // TODO: 初始化为适当的值
            byte actual;

            actual = target[index];
            Assert.IsTrue(actual == 234);
        }
Exemplo n.º 21
0
        public void CopyToTest()
        {
            ReceiveStream target = new ReceiveStream(); // TODO: 初始化为适当的值

            target.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
            byte[] dstArray = new byte[2]; // TODO: 初始化为适当的值
            int    count    = 2;           // TODO: 初始化为适当的值

            target.CopyTo(dstArray, count);
            Assert.IsTrue(dstArray[0] == 1 && dstArray[1] == 2);
        }
Exemplo n.º 22
0
 /// <summary>
 /// 收到会话发来数据
 /// </summary>
 /// <param name="session">会话</param>
 /// <param name="buffer">收到的历史数据</param>
 protected sealed override void OnReceive(TelnetSession session, ReceiveStream buffer)
 {
     while (true)
     {
         var request = TelnetRequest.Parse(buffer);
         if (request == null)
         {
             break;
         }
         this.ExecTelnetRequest(session, request);
     }
 }
Exemplo n.º 23
0
 /// <summary>
 /// 当接收到远程端的数据时,将触发此方法
 /// </summary>
 /// <param name="buffer">接收到的历史数据</param>
 protected sealed override void OnReceive(ReceiveStream buffer)
 {
     while (true)
     {
         var packet = FastPacket.From(buffer);
         if (packet == null)
         {
             break;
         }
         // 新线程处理业务内容
         Task.Factory.StartNew(() => this.OnRecvPacket(packet));
     }
 }
Exemplo n.º 24
0
        /// <summary>
        /// 当接收到会话对象的数据时,将触发此方法
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="buffer">接收到的历史数据</param>
        protected sealed override void OnReceive(T session, ReceiveStream buffer)
        {
            var handshaked = session.TagData.TryGet <bool>("HANDSHAKED");

            if (handshaked == false)
            {
                this.ProcessHandshake(session, buffer);
            }
            else
            {
                this.ProcessRequest(session, buffer);
            }
        }
Exemplo n.º 25
0
        public void CopyToTest2()
        {
            ReceiveStream target = new ReceiveStream(); // TODO: 初始化为适当的值

            target.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
            int srcOffset = 2;               // TODO: 初始化为适当的值

            byte[] dstArray  = new byte[3];; // TODO: 初始化为适当的值
            int    dstOffset = 1;            // TODO: 初始化为适当的值
            int    count     = 2;            // TODO: 初始化为适当的值

            target.CopyTo(srcOffset, dstArray, dstOffset, count);
            Assert.IsTrue(dstArray[1] == 3 && dstArray[2] == 4);
        }
Exemplo n.º 26
0
        /// <summary>
        /// 接收到策略请求
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="buffer">数据</param>
        protected sealed override void OnReceive(SessionBase session, ReceiveStream buffer)
        {
            var input     = buffer.ReadString(Encoding.UTF8);
            var policyXml = this.GeneratePolicyXml(input);

            if (policyXml != null)
            {
                var bytes = Encoding.UTF8.GetBytes(policyXml.ToCharArray());
                try
                {
                    session.Send(bytes);
                }
                catch (Exception) { }
            }
            session.Close();
        }
Exemplo n.º 27
0
        public void ProcessReplicationCreateBegin(MyPacket packet)
        {
            ReceiveStream.ResetRead(packet);

            TypeId    typeId     = ReceiveStream.ReadTypeId();
            NetworkId networkID  = ReceiveStream.ReadNetworkId();
            byte      groupCount = ReceiveStream.ReadByte();

            var pendingReplicable = new MyPendingReplicable();

            for (int i = 0; i < groupCount; i++)
            {
                var id = ReceiveStream.ReadNetworkId();
                pendingReplicable.StateGroupIds.Add(id);
            }

            Type          type       = GetTypeByTypeId(typeId);
            IMyReplicable replicable = (IMyReplicable)Activator.CreateInstance(type);

            pendingReplicable.DebugObject = replicable;

            m_pendingReplicables.Add(networkID, pendingReplicable);

            var ids = pendingReplicable.StateGroupIds;

            using (m_tmpGroups)
            {
                IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable;
                if (streamable != null)
                {
                    pendingReplicable.IsStreaming = true;
                    var group = streamable.GetStreamingStateGroup();
                    m_tmpGroups.Add(group);
                }

                for (int i = 0; i < m_tmpGroups.Count; i++)
                {
                    if (m_tmpGroups[i] != replicable)
                    {
                        AddNetworkObjectClient(ids[i], m_tmpGroups[i]);
                        pendingReplicable.StreamingGroupId = ids[i];
                    }
                }
            }

            replicable.OnLoadBegin(ReceiveStream, (loaded) => SetReplicableReady(networkID, replicable, loaded));
        }
Exemplo n.º 28
0
        public void Dispose()
        {
            try
            {
                SendStream?.Dispose();
            }
            catch (ObjectDisposedException)
            {
            }
            catch (NullReferenceException)
            {
            }
            finally
            {
                SendStream = null;
            }

            try
            {
                ReceiveStream?.Dispose();
            }
            catch (ObjectDisposedException)
            {
            }
            catch (NullReferenceException)
            {
            }
            finally
            {
                ReceiveStream = null;
            }

            try
            {
                _socket?.Dispose();
            }
            catch (ObjectDisposedException)
            {
            }
            catch (NullReferenceException)
            {
            }
            finally
            {
                _socket = null;
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ReceiveStream buffer, string boundary)
        {
            var doubleCrlf    = Encoding.ASCII.GetBytes("\r\n\r\n");
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition   = buffer.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

            var files = new List <HttpFile>();
            var form  = new HttpNameValueCollection();

            buffer.Position = buffer.Position + boundaryBytes.Length;
            while (buffer.Position < maxPosition)
            {
                var headLength = buffer.IndexOf(doubleCrlf) + doubleCrlf.Length;
                if (headLength < doubleCrlf.Length)
                {
                    break;
                }

                var head       = buffer.ReadString(headLength, Encoding.UTF8);
                var bodyLength = buffer.IndexOf(boundaryBytes);
                if (bodyLength < 0)
                {
                    break;
                }

                var mHead = new MultipartHead(head);
                if (mHead.IsFile == true)
                {
                    var stream = buffer.ReadArray(bodyLength);
                    var file   = new HttpFile(mHead, stream);
                    files.Add(file);
                }
                else
                {
                    var value = HttpUtility.UrlDecode(buffer.ReadString(bodyLength, Encoding.UTF8));
                    form.Add(mHead.Name, value);
                }
                buffer.Position = buffer.Position + boundaryBytes.Length;
            }

            request.Form  = form;
            request.Files = files.ToArray();
        }
Exemplo n.º 30
0
        /// <summary>
        /// 处理握手
        /// </summary>
        /// <param name="session">会话对象</param>
        /// <param name="buffer">接收到的数据</param>
        private void ProcessHandshake(T session, ReceiveStream buffer)
        {
            var httpRequest = default(HttpRequest);

            try
            {
                httpRequest = HttpRequest.Parse(buffer, this.LocalEndPoint, session.RemoteEndPoint);
            }
            catch (Exception)
            {
                session.Close();
                return;
            }

            // http请求的数据未完整
            if (httpRequest == null)
            {
                return;
            }

            if (this.OnHandshake(session, httpRequest) == false)
            {
                session.Close();
                return;
            }

            // 握手成功
            try
            {
                var response = new HandshakeResponse(httpRequest);
                session.SendResponse(response);
            }
            catch (Exception)
            {
            }
            finally
            {
                session.TagData.Set("HANDSHAKED", true);
            }
        }
Exemplo n.º 31
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>   
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ReceiveStream buffer, string boundary)
        {
            var doubleCrlf = Encoding.ASCII.GetBytes("\r\n\r\n");
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition = buffer.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

            var files = new List<HttpFile>();
            var form = new HttpNameValueCollection();

            buffer.Position = buffer.Position + boundaryBytes.Length;
            while (buffer.Position < maxPosition)
            {
                var headLength = buffer.IndexOf(doubleCrlf) + doubleCrlf.Length;
                if (headLength < doubleCrlf.Length)
                {
                    break;
                }

                var head = buffer.ReadString(headLength, Encoding.UTF8);
                var bodyLength = buffer.IndexOf(boundaryBytes);
                if (bodyLength < 0)
                {
                    break;
                }

                var mHead = new MultipartHead(head);
                if (mHead.IsFile == true)
                {
                    var stream = buffer.ReadArray(bodyLength);
                    var file = new HttpFile(mHead, stream);
                    files.Add(file);
                }
                else
                {
                    var value = HttpUtility.UrlDecode(buffer.ReadString(bodyLength, Encoding.UTF8));
                    form.Add(mHead.Name, value);
                }
                buffer.Position = buffer.Position + boundaryBytes.Length;
            }

            request.Form = form;
            request.Files = files.ToArray();
        }
Exemplo n.º 32
0
        /// <summary>
        /// 解析请求的数据
        /// 返回请求数据包
        /// </summary>
        /// <param name="buffer">所有收到的数据</param>  
        /// <returns></returns>
        public static unsafe FrameRequest From(ReceiveStream buffer)
        {
            if (buffer.Length < 2)
            {
                return null;
            }

            ByteBits byte0 = buffer[0];
            var fin = byte0[0];
            var frameCode = (FrameCodes)(byte)byte0.Take(4, 4);

            if (fin == false || frameCode == FrameCodes.Continuation)
            {
                return null;
            }

            var rsv = byte0.Take(1, 3);
            ByteBits byte1 = buffer[1];
            var mask = byte1[0];

            if (mask == false || Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0)
            {
                return null;
            }

            var contentLength = (int)byte1.Take(1, 7);
            buffer.Position = 2;

            if (contentLength == 127)
            {
                contentLength = (int)buffer.ReadUInt64();
            }
            else if (contentLength == 126)
            {
                contentLength = (int)buffer.ReadUInt16();
            }

            var packetLength = 6 + contentLength;
            if (buffer.Length < packetLength)
            {
                return null;
            }

            var maskingKey = buffer.ReadArray(4);
            var content = buffer.ReadArray(contentLength);
            buffer.Clear(packetLength);

            if (contentLength > 0)
            {
                fixed (byte* pcontent = &content[0], pmask = &maskingKey[0])
                {
                    for (var i = 0; i < contentLength; i++)
                    {
                        *(pcontent + i) = (byte)(*(pcontent + i) ^ *(pmask + i % 4));
                    }
                }
            }

            return new FrameRequest
            {
                Fin = fin,
                Rsv = rsv,
                Mask = mask,
                Frame = frameCode,
                ContentLength = contentLength,
                MaskingKey = maskingKey,
                Content = content
            };
        }
Exemplo n.º 33
0
        /// <summary>
        /// 解析连接请求信息
        /// 如果数据未完整则返回null
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <param name="localEndpoint">服务器的本地终结点</param>
        /// <param name="remoteEndpoint">远程端的IP和端口</param>
        /// <exception cref="HttpException"></exception>
        /// <returns></returns>
        public static HttpRequest Parse(ReceiveStream buffer, IPEndPoint localEndpoint, IPEndPoint remoteEndpoint)
        {
            buffer.Position = 0;
            var doubleCrlf = Encoding.ASCII.GetBytes("\r\n\r\n");
            var headerIndex = buffer.IndexOf(doubleCrlf);
            if (headerIndex < 0)
            {
                return null; // 数据未完整
            }

            var headerLength = headerIndex + doubleCrlf.Length;
            var headerString = buffer.ReadString(headerLength, Encoding.ASCII);
            const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" +
                @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+" +
                @"\r\n";

            var match = Regex.Match(headerString, pattern, RegexOptions.IgnoreCase);
            if (match.Success == false)
            {
                throw new HttpException(400, "请求中有语法问题,或不能满足请求");
            }

            var httpMethod = GetHttpMethod(match.Groups["method"].Value);
            var httpHeader = new HttpHeader(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures);
            var contentLength = httpHeader.TryGet<int>("Content-Length");

            if (httpMethod == HttpMethod.POST && buffer.Length - headerLength < contentLength)
            {
                return null; // 数据未完整
            }

            var request = new HttpRequest
            {
                LocalEndPoint = localEndpoint,
                RemoteEndPoint = remoteEndpoint,
                HttpMethod = httpMethod,
                Headers = httpHeader
            };

            request.Url = new Uri("http://localhost:" + localEndpoint.Port + match.Groups["path"].Value);
            request.Path = request.Url.AbsolutePath;
            request.Query = new HttpNameValueCollection(HttpUtility.UrlDecode(request.Url.Query.TrimStart('?')));

            if (httpMethod == HttpMethod.GET)
            {
                request.InputStrem = new byte[0];
                request.Form = new HttpNameValueCollection();
                request.Files = new HttpFile[0];
            }
            else
            {
                request.InputStrem = buffer.ReadArray(contentLength);
                buffer.Position = headerLength;
                HttpRequest.GeneratePostFormAndFiles(request, buffer);
            }

            buffer.Clear(headerLength + contentLength);
            return request;
        }
Exemplo n.º 34
0
        /// <summary>
        /// 生成Post得到的表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>      
        private static void GeneratePostFormAndFiles(HttpRequest request, ReceiveStream buffer)
        {
            var boundary = default(string);
            if (request.IsApplicationFormRequest() == true)
            {
                HttpRequest.GenerateApplicationForm(request);
            }
            else if (request.IsMultipartFormRequest(out boundary) == true)
            {
                if (request.InputStrem.Length >= boundary.Length)
                {
                    HttpRequest.GenerateMultipartFormAndFiles(request, buffer, boundary);
                }
            }

            if (request.Form == null)
            {
                request.Form = new HttpNameValueCollection();
            }

            if (request.Files == null)
            {
                request.Files = new HttpFile[0];
            }
        }
Exemplo n.º 35
0
        /// <summary>
        /// 解析一个数据包       
        /// 不足一个封包时返回null
        /// </summary>
        /// <param name="buffer">接收到的历史数据</param>
        /// <exception cref="ProtocolException"></exception>
        /// <returns></returns>
        public static FastPacket From(ReceiveStream buffer)
        {
            if (buffer.Length < 4)
            {
                return null;
            }

            buffer.Position = 0;
            var totalBytes = buffer.ReadInt32();
            const int packegMaxSize = 10 * 1204 * 1024; // 10M
            if (totalBytes > packegMaxSize)
            {
                throw new ProtocolException();
            }

            // 少于15字节是异常数据,清除收到的所有数据
            const int packetMinSize = 15;
            if (totalBytes < packetMinSize)
            {
                throw new ProtocolException();
            }

            // 数据包未接收完整
            if (buffer.Length < totalBytes)
            {
                return null;
            }

            // api名称数据长度
            var apiNameLength = buffer.ReadByte();
            if (totalBytes < apiNameLength + packetMinSize)
            {
                throw new ProtocolException();
            }

            // api名称数据
            var apiNameBytes = buffer.ReadArray(apiNameLength);
            // 标识符
            var id = buffer.ReadInt64();
            // 是否为客户端封包
            var isFromClient = buffer.ReadBoolean();
            // 是否异常
            var isException = buffer.ReadBoolean();
            // 实体数据
            var body = buffer.ReadArray(totalBytes - buffer.Position);

            // 清空本条数据
            buffer.Clear(totalBytes);

            var apiName = Encoding.UTF8.GetString(apiNameBytes);
            var packet = new FastPacket(apiName, id, isFromClient)
            {
                TotalBytes = totalBytes,
                ApiNameLength = apiNameLength,
                IsException = isException,
                Body = body
            };
            return packet;
        }