예제 #1
0
        public override IWebSocketFragment Filter(byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int rest)
        {
            var webSocketSession = Session;

            int total = BufferSegments.Count + length;

            if (total == SecKey3Len)
            {
                byte[] key = new byte[SecKey3Len];
                BufferSegments.CopyTo(key);
                Array.Copy(readBuffer, offset, key, BufferSegments.Count, length);
                webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = key;
                BufferSegments.ClearSegements();
                rest = 0;
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeRequestInfo);
                }
            }
            else if (total > SecKey3Len)
            {
                byte[] key = new byte[8];
                BufferSegments.CopyTo(key);
                Array.Copy(readBuffer, offset, key, BufferSegments.Count, SecKey3Len - BufferSegments.Count);
                webSocketSession.Items[WebSocketConstant.SecWebSocketKey3] = key;
                BufferSegments.ClearSegements();
                rest = total - SecKey3Len;
                if (Handshake(webSocketSession.AppServer.WebSocketProtocolProcessor, webSocketSession))
                {
                    return(HandshakeRequestInfo);
                }
            }
            else
            {
                AddArraySegment(readBuffer, offset, length, isReusableBuffer);
                rest = 0;
                NextReceiveFilter = this;
                return(null);
            }

            return(null);
        }
        /// <summary>
        /// Filters the specified session.
        /// </summary>
        /// <param name="readBuffer">The read buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param>
        /// <param name="rest">The rest.</param>
        /// <returns></returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;

            int searchEndMarkOffset;
            int searchEndMarkLength;

            //prev macthed begin mark length
            int prevMatched = 0;
            int totalParsed = 0;

            if (!m_FoundBegin)
            {
                prevMatched = m_BeginSearchState.Matched;
                int pos = readBuffer.SearchMark(offset, length, m_BeginSearchState, out totalParsed);

                if (pos < 0)
                {
                    //Don't cache invalid data
                    if (prevMatched > 0 || (m_BeginSearchState.Matched > 0 && length != m_BeginSearchState.Matched))
                    {
                        State = FilterState.Error;
                        return(NullRequestInfo);
                    }

                    return(NullRequestInfo);
                }
                else //Found the matched begin mark
                {
                    //But not at the beginning
                    if (pos != offset)
                    {
                        State = FilterState.Error;
                        return(NullRequestInfo);
                    }
                }

                //Found start mark
                m_FoundBegin = true;

                searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length - prevMatched;

                //This block only contain (part of)begin mark
                if (offset + length <= searchEndMarkOffset)
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
                    return(NullRequestInfo);
                }

                searchEndMarkLength = offset + length - searchEndMarkOffset;
            }
            else//Already found begin mark
            {
                searchEndMarkOffset = offset;
                searchEndMarkLength = length;
            }

            while (true)
            {
                var prevEndMarkMatched = m_EndSearchState.Matched;
                var parsedLen          = 0;
                var endPos             = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState, out parsedLen);

                //Haven't found end mark
                if (endPos < 0)
                {
                    rest = 0;
                    if (prevMatched > 0)//Also cache the prev matched begin mark
                    {
                        AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                    }
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                    return(NullRequestInfo);
                }

                totalParsed += parsedLen;
                rest         = length - totalParsed;

                byte[] commandData = new byte[BufferSegments.Count + prevMatched + totalParsed];

                if (BufferSegments.Count > 0)
                {
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
                }

                if (prevMatched > 0)
                {
                    Array.Copy(m_BeginSearchState.Mark, 0, commandData, BufferSegments.Count, prevMatched);
                }

                Array.Copy(readBuffer, offset, commandData, BufferSegments.Count + prevMatched, totalParsed);

                var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);

                if (!ReferenceEquals(requestInfo, NullRequestInfo))
                {
                    Reset();
                    return(requestInfo);
                }

                if (rest > 0)
                {
                    searchEndMarkOffset = endPos + m_EndSearchState.Mark.Length;
                    searchEndMarkLength = rest;
                    continue;
                }

                //Not match
                if (prevMatched > 0)//Also cache the prev matched begin mark
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                }
                AddArraySegment(readBuffer, offset, length, toBeCopied);
                return(NullRequestInfo);
            }
        }
예제 #3
0
        public override BinaryRequestInfo Filter(IAppSession <BinaryRequestInfo> session, byte[] readBuffer, int offset, int length, bool toBeCopied, out int left)
        {
            left = 0;

            if (!m_FoundStart)
            {
                var pos = readBuffer.SearchMark(offset, length, m_StartSearchState);

                //Don't cache invalid data
                if (pos < 0)
                {
                    return(null);
                }

                //Found start mark
                m_FoundStart = true;

                int searchEndMarkOffset = pos + m_StartMark.Length;

                //The end mark could not exist in this round received data
                if (offset + length <= searchEndMarkOffset)
                {
                    AddArraySegment(m_StartMark, 0, m_StartMark.Length, false);
                    return(null);
                }

                int searchEndMarkLength = offset + length - searchEndMarkOffset;

                var endPos = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState);

                if (endPos < 0)
                {
                    AddArraySegment(readBuffer, pos, length + offset - pos, toBeCopied);
                    return(null);
                }

                int parsedLen = endPos - pos + m_EndMark.Length;
                left = length - parsedLen;

                var requestInfo = CreateCommandInfo(readBuffer.CloneRange(pos, parsedLen));

                ResetState();

                return(requestInfo);
            }
            else
            {
                var endPos = readBuffer.SearchMark(offset, length, m_EndSearchState);
                //Haven't found end mark
                if (endPos < 0)
                {
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                    return(null);
                }

                //Found end mark
                int parsedLen = endPos - offset + m_EndMark.Length;
                left = length - parsedLen;

                byte[] commandData = new byte[BufferSegments.Count + parsedLen];

                if (BufferSegments.Count > 0)
                {
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
                }

                Array.Copy(readBuffer, offset, commandData, BufferSegments.Count, parsedLen);

                var requestInfo = CreateCommandInfo(commandData);

                ResetState();

                return(requestInfo);
            }
        }
예제 #4
0
        /// <summary>
        /// 该方法将会在 SuperSocket 收到一块二进制数据时被执行,接收到的数据在 readBuffer 中从 offset 开始, 长度为 length 的部分
        /// </summary>
        /// <param name="readBuffer">接收缓冲区, 接收到的数据存放在此数组里</param>
        /// <param name="offset">接收到的数据在接收缓冲区的起始位置</param>
        /// <param name="length">本轮接收到的数据的长度</param>
        /// <param name="toBeCopied">表示当你想缓存接收到的数据时,是否需要为接收到的数据重新创建一个备份而不是直接使用接收缓冲区</param>
        /// <param name="rest">这是一个输出参数, 它应该被设置为当解析到一个为政的请求后,接收缓冲区还剩余多少数据未被解析</param>
        /// <returns>组包后转化成Request对象</returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;

            int searchEndMarkOffset;
            int searchEndMarkLength;
            //上一个匹配结果
            int prevMatched = 0;

            if (!m_FoundBegin)
            {
                prevMatched = m_BeginSearchState.Matched;
                int pos = readBuffer.SearchMark(offset, length, m_BeginSearchState);

                if (pos < 0)
                {
                    //不用缓存无效数据
                    if (prevMatched > 0 || (m_BeginSearchState.Matched > 0 && length != m_BeginSearchState.Matched))
                    {
                        State = FilterState.Error;
                    }
                    return(NullRequestInfo);
                }
                //起始标识符错位
                if (pos != offset)
                {
                    State = FilterState.Error;
                    return(NullRequestInfo);
                }

                //标识已找到起始标识符
                m_FoundBegin = true;

                searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length - prevMatched;

                //这个数据块只包含起始标识
                if (offset + length <= searchEndMarkOffset)
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
                    return(NullRequestInfo);
                }

                searchEndMarkLength = offset + length - searchEndMarkOffset;
            }
            else//已经找到起始标识
            {
                searchEndMarkOffset = offset;
                searchEndMarkLength = length;
            }

            while (true)
            {
                var prevEndMarkMatched = m_EndSearchState.Matched;
                var endPos             = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState);

                //还没找到结束标识
                if (endPos < 0)
                {
                    rest = 0;
                    if (prevMatched > 0)//缓存上一个开始标识数据块
                    {
                        AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                    }
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                    return(NullRequestInfo);
                }

                //找到结束标识
                int parsedLen = endPos - offset + m_EndSearchState.Mark.Length - prevEndMarkMatched;
                rest = length - parsedLen;

                byte[] commandData = new byte[BufferSegments.Count + prevMatched + parsedLen];

                if (BufferSegments.Count > 0)
                {
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
                }

                if (prevMatched > 0)
                {
                    Array.Copy(m_BeginSearchState.Mark, 0, commandData, BufferSegments.Count, prevMatched);
                }

                Array.Copy(readBuffer, offset, commandData, BufferSegments.Count + prevMatched, parsedLen);

                var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);

                if (!ReferenceEquals(requestInfo, NullRequestInfo))
                {
                    Reset();
                    return(requestInfo);
                }

                if (rest > 0)
                {
                    searchEndMarkOffset = endPos + m_EndSearchState.Mark.Length;
                    searchEndMarkLength = rest;
                    continue;
                }

                //没有匹配结果
                if (prevMatched > 0)//缓存上一个开始标识数据块
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                }
                AddArraySegment(readBuffer, offset, length, toBeCopied);
                return(NullRequestInfo);
            }
        }
        /// <summary>
        /// Filters the specified session.
        /// </summary>
        /// <param name="readBuffer">The read buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param>
        /// <param name="rest">The rest.</param>
        /// <returns></returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;

            if (!m_FoundBegin)
            {
                var pos = readBuffer.SearchMark(offset, length, m_BeginSearchState);

                //Don't cache invalid data
                if (pos < 0)
                {
                    return(NullRequestInfo);
                }

                //Found start mark
                m_FoundBegin = true;

                int searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length;

                //The end mark could not exist in this round received data
                if (offset + length <= searchEndMarkOffset)
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
                    return(NullRequestInfo);
                }

                int searchEndMarkLength = offset + length - searchEndMarkOffset;

                var endPos = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState);

                if (endPos < 0)
                {
                    AddArraySegment(readBuffer, pos, length + offset - pos, toBeCopied);
                    return(NullRequestInfo);
                }

                int parsedLen = endPos - pos + m_EndSearchState.Mark.Length;
                rest = length - parsedLen;

                var requestInfo = ProcessMatchedRequest(readBuffer, pos, parsedLen);

                Reset();

                return(requestInfo);
            }
            else
            {
                var endPos = readBuffer.SearchMark(offset, length, m_EndSearchState);
                //Haven't found end mark
                if (endPos < 0)
                {
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                    return(NullRequestInfo);
                }

                //Found end mark
                int parsedLen = endPos - offset + m_EndSearchState.Mark.Length;
                rest = length - parsedLen;

                byte[] commandData = new byte[BufferSegments.Count + parsedLen];

                if (BufferSegments.Count > 0)
                {
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
                }

                Array.Copy(readBuffer, offset, commandData, BufferSegments.Count, parsedLen);

                var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);

                Reset();

                return(requestInfo);
            }
        }
예제 #6
0
        /// <summary>
        /// 过滤指定的会话
        /// </summary>
        /// <param name="readBuffer">数据缓存</param>
        /// <param name="offset">数据起始位置</param>
        /// <param name="length">缓存长度</param>
        /// <param name="toBeCopied"></param>
        /// <param name="rest"></param>
        /// <returns></returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;
            int searchEndMarkOffset;
            int searchEndMarkLength;

            //在此处做了处理,将接收到的第一个字符作为起始过滤标志,到结束。返回指定长度的数据。
            byte[] startMark = new byte[] { readBuffer[offset] };
            byte[] endMark   = new byte[] { 0xff };
            m_BeginSearchState = new SearchMarkState <byte>(startMark);
            m_EndSearchState   = new SearchMarkState <byte>(endMark);
            //上一个开始标记长度
            int prevMatched = 0;
            int totalParsed = 0;

            if (!m_FoundBegin)
            {
                prevMatched = m_BeginSearchState.Matched;
                int pos = readBuffer.SearchMark(offset, length, m_BeginSearchState, out totalParsed);

                if (pos < 0)
                {
                    //不要缓存无效数据
                    if (prevMatched > 0 || (m_BeginSearchState.Matched > 0 && length != m_BeginSearchState.Matched))
                    {
                        State = FilterState.Error;
                        return(NullRequestInfo);
                    }

                    return(NullRequestInfo);
                }
                else //找到匹配的开始标记
                {
                    //But not at the beginning
                    if (pos != offset)
                    {
                        State = FilterState.Error;
                        return(NullRequestInfo);
                    }
                }

                //找到开始标记
                m_FoundBegin = true;

                searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length - prevMatched;

                //This block only contain (part of)begin mark
                if (offset + length <= searchEndMarkOffset)
                {
                    AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
                    return(NullRequestInfo);
                }

                searchEndMarkLength = offset + length - searchEndMarkOffset;
            }
            else//Already found begin mark
            {
                searchEndMarkOffset = offset;
                searchEndMarkLength = length;
            }

            while (true)
            {
                var prevEndMarkMatched = m_EndSearchState.Matched;
                var parsedLen          = 0;
                var endPos             = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState, out parsedLen);

                //没有找到结束标记
                if (endPos < 0)
                {
                    rest = 0;
                    if (prevMatched > 0)//还缓存先前匹配的开始标记
                    {
                        AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                    }
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                }

                //totalParsed += parsedLen;
                //rest = length - totalParsed;
                totalParsed = 0;
                byte[] commandData = new byte[BufferSegments.Count + prevMatched + totalParsed];

                if (BufferSegments.Count > 0)
                {
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);
                }

                if (prevMatched > 0)
                {
                    Array.Copy(m_BeginSearchState.Mark, 0, commandData, BufferSegments.Count, prevMatched);
                }

                Array.Copy(readBuffer, offset, commandData, BufferSegments.Count + prevMatched, totalParsed);

                var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);

                Reset();
                return(requestInfo);
            }
        }