/// <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 virtual TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { //获取包头信息 ChainProtocol hp = new ChainProtocol(); result = readBuffer.SearchMark(offset, length, m_SearchState); if (result == -1) { rest = -1; } else { m_Size = result - offset; byte[] headerdata = new byte[m_Size]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, m_Size); ChainHeader chainHeader = hp.GetChainHeader(headerdata); rest = m_ParsedLength + length - m_Size; } if (rest >= 0) { var requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLength, m_Size, toBeCopied); InternalReset(); return(requestInfo); } else { m_ParsedLength += length; m_OffsetDelta = m_ParsedLength; rest = 0; var expectedOffset = offset + length; var newOffset = m_OrigOffset + m_OffsetDelta; if (newOffset < expectedOffset) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLength + length, readBuffer, m_OrigOffset, m_ParsedLength); } return(NullRequestInfo); } }
/// <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 TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; TRequestInfo requestInfo; int prevMatched = m_SearchState.Matched; int result = 0; var findLen = result - offset; int remainlen = 0; //Debug.WriteLine("缓存:" + this.BufferSegments.Count); //判断缓存是否存在,如果存在说明之前数据没有取完,出现粘包 if (this.BufferSegments.Count > 0) { if (packLength == 0)//说明之前的数据只有部分包头信息,没能进行解析包头信息 { ////////// //把缓存的数据加上新收到的数据合并的总接收到的数据,进行查找 int receivedLen = length + this.LeftBufferSize; byte[] receivedData = new byte[receivedLen]; Buffer.BlockCopy(this.BufferSegments.ToArray(), 0, receivedData, 0, this.BufferSegments.Count); Buffer.BlockCopy(readBuffer, offset, receivedData, this.BufferSegments.Count, length); result = receivedData.SearchMark(0, receivedLen, m_SearchState); findLen = result - this.LeftBufferSize; if (findLen > 0)//找到包头的数据 { byte[] headerdata = new byte[findLen + this.BufferSegments.Count]; Buffer.BlockCopy(this.BufferSegments.ToArray(), 0, headerdata, 0, this.BufferSegments.Count); Buffer.BlockCopy(readBuffer, offset, headerdata, this.BufferSegments.Count, findLen); ChainProtocol hp = new ChainProtocol(); chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; } else { int contentLen = Convert.ToInt32(chainHeader.Data["Content-Length"]); packLength = headerdata.Length + contentLen + m_SearchState.Mark.Length; //包的长度大于接收的长度,则需要缓存下来等下一个包数据过来进行拼接 if (packLength > (length + this.LeftBufferSize)) { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 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); } else if (packLength <= (length + this.LeftBufferSize))//包的长度小于接收的数据长度加上缓存长度,则生成该包,并把多余的数据缓存下来 { //包的长度刚好等于接收的数据长度,则生成该包即可 //Debug.WriteLine("packLength:{0} < length:{1}".FormatString(packLength,length)); findLen = packLength - this.LeftBufferSize; } } } else//第一个包的数据不够一个包头的长度 { 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); } /////////// } else { //剩余的数据包大小 remainlen = packLength - this.BufferSegments.Count; if (remainlen > 0 && remainlen <= length)//说明剩余的数据等于本次接收的数据//剩余数据小于本次接收的数据长度,则需要重新组包 { findLen = remainlen; } else if (remainlen > 0 && remainlen > length)//剩余数据大于接收得到数据长度,需要缓存下来,等下一个包过来进行拼接 { 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; } //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; ////// // m_ParsedLengthInBuffer += length; // m_ParsedLengthInBuffer = 0; // m_OffsetDelta = 0; return(NullRequestInfo); } else if (remainlen < 0)//不存在 { } } } else//没有缓存则需要直接获取数据 { result = readBuffer.SearchMark(offset, length, m_SearchState); findLen = result - offset; if (findLen > 0)//找到包头的数据 { byte[] headerdata = new byte[findLen]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, findLen); ChainProtocol hp = new ChainProtocol(); chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; } else { int contentLen = Convert.ToInt32(chainHeader.Data["Content-Length"]); packLength = headerdata.Length + contentLen + m_SearchState.Mark.Length; //包的长度大于接收的长度,则需要缓存下来等下一个包数据过来进行拼接 if (packLength > length) { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 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); } else if (packLength <= length) //包的长度小于接收的数据长度,则生成该包,并把多余的数据缓存下来 { //包的长度刚好等于接收的数据长度,则生成该包即可 findLen = packLength; } } } else//第一个包的数据不够一个包头的长度 { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 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); } } //计算偏移 rest = length - findLen + prevMatched; if (findLen > 0) { if (this.BufferSegments != null && this.LeftBufferSize > 0) { //Debug.WriteLine("包大小{0},缓存大小{1},接收大小{2}".FormatString(packLength,this.LeftBufferSize, length)); 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 (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> /// 把byte[] source解析成Chain包 /// </summary> /// <param name="source"></param> /// <returns></returns> public ChainPackage ParseRequestInfo(byte[] source) { IPackageProtocol <ChainPackage> packageHeadProtocol = new ChainProtocol(); return(packageHeadProtocol.ResolveProtocol(source)); }
internal byte[] ToByte() { ChainProtocol cpcl = new ChainProtocol(); return(cpcl.ResolveProtocol(this)); }