public override string ToString() { var bytes = BufferSegments.ToArray(); var value = Encoding.UTF8.GetString(bytes); return($"[{Type}]{value}"); }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="session">The session.</param> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="left">The left, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override TRequestInfo Filter(IAppSession <TRequestInfo> session, byte[] readBuffer, int offset, int length, bool toBeCopied, out int left) { left = 0; int prevMatched = m_SearchState.Matched; int result = readBuffer.SearchMark(offset, length, m_SearchState); if (result < 0) { this.AddArraySegment(readBuffer, offset, length, toBeCopied); return(m_NullRequestInfo); } int findLen = result - offset; if (findLen > 0) { this.AddArraySegment(readBuffer, offset, findLen, false); } else if (prevMatched > 0) { BufferSegments.TrimEnd(prevMatched); } var requestInfo = Resolve(BufferSegments); ClearBufferSegments(); left = length - findLen - (m_SearchState.Mark.Length - prevMatched); return(requestInfo); }
public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; int leftLength = m_Length - BufferSegments.Count; AddArraySegment(readBuffer, offset, length, isReusableBuffer); if (length >= leftLength) { NextCommandReader = new MyCommandReader(AppServer); var commandInfo = new BinaryCommandInfo(m_CommandName, BufferSegments.ToArrayData(0, m_Length)); if (length > leftLength) { left = length - leftLength; } return(commandInfo); } else { NextCommandReader = this; return(null); } }
public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { NextCommandReader = this; left = 0; if (LeftBufferSize + length <= DataLength) { AddArraySegment(readBuffer, offset, length, isReusableBuffer); if (LeftBufferSize < DataLength) { return(null); } } else { AddArraySegment(readBuffer, offset, DataLength - LeftBufferSize, false); left = length - (DataLength - LeftBufferSize); } NextCommandReader = PrevCommandReader; var cmdInfo = new BinaryCommandInfo(CommandId.ToString(), BufferSegments.ToArrayData()); ClearBufferSegments(); return(cmdInfo); }
public override BinaryRequestInfo Filter(IAppSession <BinaryRequestInfo> session, byte[] readBuffer, int offset, int length, bool toBeCopied, out int left) { left = 0; int leftLength = m_Length - BufferSegments.Count; AddArraySegment(readBuffer, offset, length, toBeCopied); if (length >= leftLength) { NextRequestFilter = new MyRequestFilter(); var requestInfo = new BinaryRequestInfo(m_CommandName, BufferSegments.ToArrayData(0, m_Length)); if (length > leftLength) { left = length - leftLength; } return(requestInfo); } else { NextRequestFilter = this; return(null); } }
public override WebSocketCommandInfo GetCommandInfo(byte[] readBuffer, int offset, int length, out int left) { left = 0; var prevMatched = m_HeadSeachState.Matched; var result = readBuffer.SearchMark(offset, length, m_HeadSeachState); if (result < 0) { AddArraySegment(readBuffer, offset, length); return(null); } int findLen = result - offset; string handshake = string.Empty; if (this.BufferSegments.Count > 0) { if (findLen > 0) { this.AddArraySegment(readBuffer, offset, findLen); handshake = this.BufferSegments.Decode(Encoding.UTF8); } else { handshake = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched); } } else { handshake = Encoding.UTF8.GetString(readBuffer, offset, findLen); } left = length - findLen - (HeaderTerminator.Length - prevMatched); BufferSegments.ClearSegements(); if (!handshake.StartsWith(m_BadRequestPrefix, StringComparison.OrdinalIgnoreCase)) { return(new WebSocketCommandInfo { Key = OpCode.Handshake.ToString(), Text = handshake }); } else { return(new WebSocketCommandInfo { Key = OpCode.BadRequest.ToString(), Text = handshake }); } }
public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; int lastSegmentOffset = BufferSegments.Count; int searchEndMarkLength = length; this.AddArraySegment(readBuffer, offset, length, isReusableBuffer); if (!m_FoundStart) { var pos = BufferSegments.SearchMark(lastSegmentOffset, length, m_StartMark); if (!pos.HasValue || pos.Value < 0) { return(null); } //Found start mark m_StartPos = pos.Value; m_FoundStart = true; lastSegmentOffset = pos.Value + 2; //The end mark could not exist in this round received data if (lastSegmentOffset + 2 > BufferSegments.Count) { return(null); } searchEndMarkLength = BufferSegments.Count - lastSegmentOffset; } var endPos = BufferSegments.SearchMark(lastSegmentOffset, searchEndMarkLength, m_EndMark); //Haven't found end mark if (!endPos.HasValue || endPos.Value < 0) { return(null); } //Found end mark left = BufferSegments.Count - endPos.Value - 2; var commandData = BufferSegments.ToArrayData(m_StartPos, endPos.Value - m_StartPos + 2); var commandInfo = new BinaryCommandInfo(BitConverter.ToString(commandData, 15, 1), commandData); //Reset state m_FoundStart = false; m_StartPos = -1; BufferSegments.ClearSegements(); return(commandInfo); }
/// <summary> /// Adds the array into BufferSegments. /// </summary> /// <param name="buffer">The buffer which will be added into BufferSegments.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</param> /// <param name="isReusableBuffer">if set to <c>true</c> [is reusable buffer].</param> protected void AddArraySegment(byte[] buffer, int offset, int length, bool isReusableBuffer) { if (isReusableBuffer) { BufferSegments.AddSegment(new ArraySegment <byte>(buffer.CloneRange(offset, length))); } else { BufferSegments.AddSegment(new ArraySegment <byte>(buffer, offset, length)); } }
void Reset(bool clearBuffer) { m_Type = null; m_Length = null; m_TempLength = 0; if (clearBuffer) { BufferSegments.ClearSegements(); } }
/// <summary> /// Finds the command. /// "SEND 0008 xg^89W(v" /// Read 10 chars as command name and command data length /// </summary> /// <param name="session">The session.</param> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</param> /// <param name="isReusableBuffer">if set to <c>true</c> [is reusable buffer].</param> /// <returns></returns> public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; int leftLength = 10 - this.BufferSegments.Count; if (length < leftLength) { AddArraySegment(readBuffer, offset, length, isReusableBuffer); NextCommandReader = this; return(null); } AddArraySegment(readBuffer, offset, leftLength, isReusableBuffer); string commandName = BufferSegments.Decode(Encoding.ASCII, 0, 4); int commandDataLength = Convert.ToInt32(BufferSegments.Decode(Encoding.ASCII, 5, 4).TrimStart('0')); if (length > leftLength) { int leftDataLength = length - leftLength; if (leftDataLength >= commandDataLength) { byte[] commandData = readBuffer.CloneRange(offset + leftLength, commandDataLength); BufferSegments.ClearSegements(); NextCommandReader = this; var commandInfo = new BinaryCommandInfo(commandName, commandData); //The next commandInfo is comming if (leftDataLength > commandDataLength) { left = leftDataLength - commandDataLength; } return(commandInfo); } else// if (leftDataLength < commandDataLength) { //Clear previous cached header data BufferSegments.ClearSegements(); //Save left data part AddArraySegment(readBuffer, offset + leftLength, length - leftLength, isReusableBuffer); NextCommandReader = GetMyCommandDataReader(commandName, commandDataLength); return(null); } } else//length == leftLength { BufferSegments.ClearSegements(); NextCommandReader = GetMyCommandDataReader(commandName, commandDataLength); return(null); } }
public override BinaryRequestInfo Filter(IAppSession <BinaryRequestInfo> session, byte[] readBuffer, int offset, int length, bool toBeCopied, out int left) { left = 0; int leftLength = 6 - this.BufferSegments.Count; if (length < leftLength) { AddArraySegment(readBuffer, offset, length, toBeCopied); NextRequestFilter = this; return(null); } AddArraySegment(readBuffer, offset, leftLength, toBeCopied); string commandName = BufferSegments.Decode(Encoding.ASCII, 0, 4); int commandDataLength = (int)BufferSegments[4] * 256 + (int)BufferSegments[5]; if (length > leftLength) { int leftDataLength = length - leftLength; if (leftDataLength >= commandDataLength) { byte[] commandData = readBuffer.CloneRange(offset + leftLength, commandDataLength); BufferSegments.ClearSegements(); NextRequestFilter = this; var requestInfo = new BinaryRequestInfo(commandName, commandData); //The next requestInfo is comming if (leftDataLength > commandDataLength) { left = leftDataLength - commandDataLength; } return(requestInfo); } else// if (leftDataLength < commandDataLength) { //Clear previous cached header data BufferSegments.ClearSegements(); //Save left data part AddArraySegment(readBuffer, offset + leftLength, length - leftLength, toBeCopied); NextRequestFilter = GetMyCommandDataReader(commandName, commandDataLength); return(null); } } else { NextRequestFilter = GetMyCommandDataReader(commandName, commandDataLength); return(null); } }
protected bool FindCommandInfoDirectly(byte[] readBuffer, int offset, int length, bool isReusableBuffer, out string command, out int left) { left = 0; ArraySegment <byte> currentSegment; if (isReusableBuffer) { //Next received data also will be saved in this buffer, so we should create a new byte[] to persistent current received data currentSegment = new ArraySegment <byte>(readBuffer.CloneRange(offset, length)); } else { currentSegment = new ArraySegment <byte>(readBuffer, offset, length); } BufferSegments.AddSegment(currentSegment); int?result = BufferSegments.SearchMark(Terminator); if (!result.HasValue) { command = string.Empty; return(false); } if (result.Value < 0) { command = string.Empty; return(false); } int findLen = result.Value + Terminator.Length; int total = BufferSegments.Count; command = Encoding.GetString(BufferSegments.ToArrayData(0, result.Value)); ClearBufferSegments(); if (findLen < total) { left = total - findLen; } return(true); }
public override BinaryCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; this.AddArraySegment(readBuffer, offset, length, isReusableBuffer); if (length < 14) { BufferSegments.ClearSegements(); return(null); } var commandData = BufferSegments.ToArrayData(0, length); BufferSegments.ClearSegements(); return(new BinaryCommandInfo("WMDEVICE", commandData)); }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <seealso cref="https://github.com/welly87/serveractor/blob/master/ServerActor/Libs/SuperSocket(1.5.3).Source/SocketBase/Protocol/TerminatorReceiveFilter.cs"/> /// <seealso cref="https://github.com/Snowin1994/USV_HEU/blob/f9e063366ba5abe89492a4e8a674f920c54067bc/USV_Server/TerminatorReceiveFilter.cs"/> public override PackageChat Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; PackageChat Package = null; if ((BufferSegments != null) && (BufferSegments.Count > 0)) { _parsedLengthInBuffer += length; AddArraySegment(readBuffer, offset, length, toBeCopied); byte[] Content = BufferSegments.ToArrayData(0, _parsedLengthInBuffer); Package = _ResolvePackageChat(Content, 0, Content.Length); int totalLength = (Package != null) ? headerSize + Package.HeaderContentLength : 0; rest = _parsedLengthInBuffer - totalLength; } else { Package = _ResolvePackageChat(readBuffer, offset, length); if (Package == null) { _parsedLengthInBuffer += length; AddArraySegment(readBuffer, offset, length, toBeCopied); return(null); } else { int totalLength = headerSize + Package.HeaderContentLength; rest = length - totalLength; } } base.Reset(); return(Package); }
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); }
private void AppendValue(ViewBufferValue value) { ViewBufferValue[] segment; if (BufferSegments == null) { BufferSegments = new List <ViewBufferValue[]>(1); segment = _bufferScope.GetSegment(); BufferSegments.Add(segment); } else { segment = BufferSegments[BufferSegments.Count - 1]; if (CurrentCount == segment.Length) { segment = _bufferScope.GetSegment(); BufferSegments.Add(segment); CurrentCount = 0; } } segment[CurrentCount] = value; CurrentCount++; }
public override WebSocketCommandInfo GetCommandInfo(byte[] readBuffer, int offset, int length, out int left) { left = 0; // prevMatched is needed because handshake may have come // in a number of segments, and the HeaderTerminator that // we're looking for might lie across previous segments // and `readBuffer`. // // More precisely, prevMatched > 0 if and only if the last // byte(s) at end of the previous segment **started like** // an incomplete HeaderTerminator that **may or may not** // be continued and completed in current `readBuffer`. -- // fidergo-stephane-gourichon var prevMatched = m_HeadSeachState.Matched; // At this point in code **we don't know yet** if the // `prevMatched` bytes that match the `HeaderTerminator` // at end of previous segment are part of a **full match** // (in this case the value of `prevMatched` is useful) or // just a **partial** (in that cas the value of // `prevMatched` is irrelevant). var result = readBuffer.SearchMark(offset, length, m_HeadSeachState); if (result < 0) { // We've not found the HeaderTerminator yet. We'll be // called again when more data arrives. -- // fidergo-stephane-gourichon AddArraySegment(readBuffer, offset, length); return(null); } // We've found the HeaderTerminator. All might be in // readBuffer, or handshake might be cut across the last // segment, or just the HeaderTerminator might be in // readBuffer or even cut across. We must handle all // those cases. -- fidergo-stephane-gourichon int findLen = result - offset; string handshake = string.Empty; if (this.BufferSegments.Count > 0) { if (findLen > 0) { // In this code path we know that the handshake // was cut across at least previous segments and // `readBuffer`. In other words, // `readBuffer[offset]` starts with at least one // byte that belongs to the handshake proper // (excluding `HeaderTerminator`). So, we add // those bytes and extract the handshake. this.AddArraySegment(readBuffer, offset, findLen); handshake = this.BufferSegments.Decode(Encoding.UTF8); // Now, we need to correct `prevMatched`. Indeed, // in this code path, any byte(s) matched at end // of previous segment were not part of an actual // HeaderTerminator cut across. If // `prevMatched`>0, such byte(s) was / were a // partial match that `readBuffer` content // disproved. // // So, basically, there were actually zero bytes // of the actual `HeaderTerminator` match in // previous segment. We reflect that by setting // prevMatched = 0. -- fidergo-stephane-gourichon prevMatched = 0; // If we did not set prevMatched to zero, `left` // would be too big and our read pointer would not // advance enough, causing desynchronization in WS // protocol decoding, failure to recognize further // messages, server closing connection for lack of // reply to ping. -- fidergo-stephane-gourichon } else { // The handshake was actually fully inside the // previous segment. That segment possibly ended // with `prevMatch` bytes of the // `HeaderTerminator` that we have to shave // off. -- fidergo-stephane-gourichon handshake = this.BufferSegments.Decode(Encoding.UTF8, 0, this.BufferSegments.Count - prevMatched); } } else { // In this code path, there was no previous segment. // Everything is in `readBuffer`. handshake = Encoding.UTF8.GetString(readBuffer, offset, findLen); // I'm nearly sure prevMatched is always zero already, // if reset between invocations (see below // `m_HeadSeachState.Matched = 0`). I'm definitely // sure it should be zero here. An assert would be // good. As a fallback set it. -- // fidergo-stephane-gourichon prevMatched = 0; } // We must tell caller how many bytes are left, with a // formula that works in all cases. // It works if prevMatched reflects actual match, not // partial match, as set to zero above. -- // fidergo-stephane-gourichon left = length - findLen - (HeaderTerminator.Length - prevMatched); // Rationale: left bytes are all bytes minus bytes // consumed. We consume the part of the handshake that's // in `readBuffer`, which is `findLen` bytes. We also // consume the part of the `HeaderTerminator` that is in // `readBuffer`, which is `(HeaderTerminator.Length - // prevMatched)` bytes. BufferSegments.ClearSegements(); // In case the object is reused, reset search state. I'm // nearly sure this is always zero already. An assert // would be good. As a fallback set it. -- // fidergo-stephane-gourichon m_HeadSeachState.Matched = 0; if (!handshake.StartsWith(m_BadRequestPrefix, StringComparison.OrdinalIgnoreCase)) { return(new WebSocketCommandInfo { Key = OpCode.Handshake.ToString(), Text = handshake }); } else { return(new WebSocketCommandInfo { Key = OpCode.BadRequest.ToString(), Text = handshake }); } }
public override IWebSocketFragment Filter(IAppSession <IWebSocketFragment> session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left) { left = 0; var skipByteCount = 0; if (!m_Type.HasValue) { byte startByte = readBuffer[offset]; skipByteCount = 1; m_Type = startByte; } //0xxxxxxx: Collect protocol data by end mark if ((m_Type.Value & 0x80) == 0x00) { byte lookForByte = 0xFF; int i; for (i = offset + skipByteCount; i < offset + length; i++) { if (readBuffer[i] == lookForByte) { left = length - (i - offset + 1); if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount)); Reset(); return(commandInfo); } else { AddArraySegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return(commandInfo); } } } AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount, isReusableBuffer); return(null); } else//10000000: Collect protocol data by length { while (!m_Length.HasValue) { if (length <= skipByteCount) { //No data to read return(null); } byte lengthByte = readBuffer[skipByteCount]; //Closing handshake if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType) { session.Close(CloseReason.ClientClosing); return(null); } int thisLength = (int)(lengthByte & 0x7F); m_TempLength = m_TempLength * 128 + thisLength; skipByteCount++; if ((lengthByte & 0x80) != 0x80) { m_Length = m_TempLength; break; } } int requiredSize = m_Length.Value - BufferSegments.Count; int leftSize = length - skipByteCount; if (leftSize < requiredSize) { AddArraySegment(readBuffer, skipByteCount, length - skipByteCount, isReusableBuffer); return(null); } else { left = leftSize - requiredSize; if (BufferSegments.Count <= 0) { var commandInfo = new PlainFragment(Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize)); Reset(); return(commandInfo); } else { AddArraySegment(readBuffer, offset + skipByteCount, requiredSize, false); var commandInfo = new PlainFragment(BufferSegments.Decode(Encoding.UTF8)); Reset(); return(commandInfo); } } } }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; int prevMatched = m_SearchState.Matched; int result = readBuffer.SearchMark(offset, length, m_SearchState); var findLen = result - offset; var packageLen = 0; //当在收到的数据中没有找到头信息,可能情况:1头信息不完整,2可能是在上一个包中已经存在头信息 if (result <= 0) { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } rest = 0; return(NullRequestInfo); } else if (result > 0 && findLen > 0) //头信息完整,并且获得到了头信息,并得到该包的大小。当在一次获取时得到了包的信息 { byte[] headerdata = new byte[findLen]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, findLen); ChainProtocol hp = new ChainProtocol(); ChainHeader chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; packageLen = findLen; } else { int contentLen = Convert.ToInt32(chainHeader.Data.Get("Content-Length")); packageLen = contentLen + findLen; //findLen += contentLen + m_SearchState.Mark.Length; if ((readBuffer.Length - offset) >= packageLen) { findLen += contentLen + m_SearchState.Mark.Length; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; m_OffsetDelta += length; return(NullRequestInfo); } m_OffsetDelta += length; } } } rest = length - findLen - (m_SearchState.Mark.Length - prevMatched); TRequestInfo requestInfo; //当收到最后的数据时,进行组织包 if (findLen > 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer); } } else if (findLen <= 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } else if (prevMatched > 0) { if (m_ParsedLengthInBuffer > 0) { if (m_ParsedLengthInBuffer < prevMatched) { BufferSegments.TrimEnd(prevMatched - m_ParsedLengthInBuffer); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched); } } } else { BufferSegments.TrimEnd(prevMatched); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if (rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return(requestInfo); }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override USVRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { #region 将string数据写入文件 - 已注释 string Temp = Encoding.Default.GetString(readBuffer, offset, length) + System.Environment.NewLine; string path = @"..\\USVALLData.txt"; FileStream f = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(f); sw.WriteLine(Temp); sw.Flush(); sw.Close(); f.Close(); #endregion rest = 0; int prevMatched = m_SearchState.Matched; int result = readBuffer.SearchMark(offset, length, m_SearchState); if (result < 0) { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= 4096) //4096m_Session.Config.ReceiveBufferSize { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } var findLen = result - offset; var currentMatched = m_SearchState.Mark.Length - prevMatched; //The prev matched part is not belong to the current matched terminator mark if (prevMatched > 0 && findLen != 0) { //rest prevMatched to 0 prevMatched = 0; currentMatched = m_SearchState.Mark.Length; } rest = length - findLen - currentMatched; USVRequestInfo requestInfo; if (findLen > 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer); } } else if (prevMatched > 0) { if (m_ParsedLengthInBuffer > 0) { if (m_ParsedLengthInBuffer < prevMatched) { BufferSegments.TrimEnd(prevMatched - m_ParsedLengthInBuffer); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched); } } } else { BufferSegments.TrimEnd(prevMatched); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { if (m_ParsedLengthInBuffer > 0) { this.BufferSegments.AddSegment(readBuffer, offset, m_ParsedLengthInBuffer); } requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if (rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return(requestInfo); }
/// <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> /// Adds the array segment into BufferSegment. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</param> protected void AddArraySegment(byte[] buffer, int offset, int length) { BufferSegments.AddSegment(buffer, offset, length, true); }
public override WebSocketCommandInfo GetCommandInfo(byte[] readBuffer, int offset, int length, out int left) { left = 0; var skipByteCount = 0; if (!m_Type.HasValue) { byte startByte = readBuffer[offset]; skipByteCount = 1; m_Type = startByte; } //0xxxxxxx: Collect protocol data by end mark if ((m_Type.Value & 0x80) == 0x00) { byte lookForByte = 0xFF; int i; for (i = offset + skipByteCount; i < offset + length; i++) { if (readBuffer[i] == lookForByte) { left = length - (i - offset + 1); if (BufferSegments.Count <= 0) { var commandInfo = new WebSocketCommandInfo(OpCode.Text.ToString(), Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, i - offset - skipByteCount)); Reset(false); return(commandInfo); } else { this.BufferSegments.AddSegment(readBuffer, offset + skipByteCount, i - offset - skipByteCount, false); var commandInfo = new WebSocketCommandInfo(OpCode.Text.ToString(), BufferSegments.Decode(Encoding.UTF8)); Reset(true); return(commandInfo); } } } this.AddArraySegment(readBuffer, offset + skipByteCount, length - skipByteCount); return(null); } else //10000000: Collect protocol data by length { while (!m_Length.HasValue) { if (length <= skipByteCount) { //No data to read return(null); } byte lengthByte = readBuffer[skipByteCount]; //Closing handshake if (lengthByte == 0x00 && m_Type.Value == m_ClosingHandshakeType) { var commandInfo = new WebSocketCommandInfo(OpCode.Close.ToString()); Reset(true); return(commandInfo); } int thisLength = (int)(lengthByte & 0x7F); m_TempLength = m_TempLength * 128 + thisLength; skipByteCount++; if ((lengthByte & 0x80) != 0x80) { m_Length = m_TempLength; break; } } int requiredSize = m_Length.Value - BufferSegments.Count; int leftSize = length - skipByteCount; if (leftSize < requiredSize) { this.AddArraySegment(readBuffer, skipByteCount, length - skipByteCount); return(null); } else { left = leftSize - requiredSize; if (BufferSegments.Count <= 0) { var commandInfo = new WebSocketCommandInfo(OpCode.Text.ToString(), Encoding.UTF8.GetString(readBuffer, offset + skipByteCount, requiredSize)); Reset(false); return(commandInfo); } else { this.BufferSegments.AddSegment(readBuffer, offset + skipByteCount, requiredSize, false); var commandInfo = new WebSocketCommandInfo(BufferSegments.Decode(Encoding.UTF8)); Reset(true); return(commandInfo); } } } }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; int prevMatched = m_SearchState.Matched; int result = readBuffer.SearchMark(offset, length, m_SearchState); if (result < 0) { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } var findLen = result - offset; var currentMatched = m_SearchState.Mark.Length - prevMatched; //The prev matched part is not belong to the current matched terminator mark if (prevMatched > 0 && findLen != 0) { //rest prevMatched to 0 prevMatched = 0; currentMatched = m_SearchState.Mark.Length; } rest = length - findLen - currentMatched; TRequestInfo requestInfo; if (findLen > 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer); } } else if (prevMatched > 0) { if (m_ParsedLengthInBuffer > 0) { if (m_ParsedLengthInBuffer < prevMatched) { BufferSegments.TrimEnd(prevMatched - m_ParsedLengthInBuffer); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched); } } } else { BufferSegments.TrimEnd(prevMatched); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { if (m_ParsedLengthInBuffer > 0) { this.BufferSegments.AddSegment(readBuffer, offset, m_ParsedLengthInBuffer); } requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if (rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return(requestInfo); }
public bool Equals(XmlToken token) { return(Type.Equals(token.Type) && BufferSegments.Equals(token.BufferSegments)); }
public override int GetHashCode() { return(Type.GetHashCode() ^ BufferSegments.GetHashCode()); }
/// <summary> /// Clears the buffer segments. /// </summary> protected void ClearBufferSegments() { BufferSegments.ClearSegements(); }
/// <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); } }
/// <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); } }
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); } }