SuperSocket内置的命令行协议的解析
SuperSocket\SocketBase\Protocol\TerminatorReceiveFilter.cs
/// <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; }
protected override StringRequestInfo ProcessMatchedRequest(byte[] data, int offset, int length) { if(length == 0) return m_RequestParser.ParseRequestInfo(string.Empty); return m_RequestParser.ParseRequestInfo(m_Encoding.GetString(data, offset, length)); }
SuperSocket\SocketBase\Protocol\TerminatorReceiveFilter.cs
TerminatorReceiveFilter.cs文件包含2个类
public abstract class TerminatorReceiveFilter<TRequestInfo> : ReceiveFilterBase<TRequestInfo>, IOffsetAdapter, IReceiveFilterInitializer where TRequestInfo : IRequestInfo
public class TerminatorReceiveFilter : TerminatorReceiveFilter<StringRequestInfo>
SuperSocket\SocketBase\Protocol\StringRequestInfo.cs
public class StringRequestInfo : RequestInfo<string>
AppSession在初始化的时候,指定了ReceiveFilter
SuperSocket\SocketBase\AppSession.cs
/// <summary> /// Initializes the specified app session by AppServer and SocketSession. /// </summary> /// <param name="appServer">The app server.</param> /// <param name="socketSession">The socket session.</param> public virtual void Initialize(IAppServer<TAppSession, TRequestInfo> appServer, ISocketSession socketSession) { var castedAppServer = (AppServerBase<TAppSession, TRequestInfo>)appServer; AppServer = castedAppServer; Charset = castedAppServer.TextEncoding; SocketSession = socketSession; SessionID = socketSession.SessionID; m_Connected = true; m_ReceiveFilter = castedAppServer.ReceiveFilterFactory.CreateFilter(appServer, this, socketSession.RemoteEndPoint); var filterInitializer = m_ReceiveFilter as IReceiveFilterInitializer; if (filterInitializer != null) filterInitializer.Initialize(castedAppServer, this); socketSession.Initialize(this); OnInit(); }
F:\CodeForGitBlit\SuperSocket\SocketBase\AppServer.cs
internal override IReceiveFilterFactory<StringRequestInfo> CreateDefaultReceiveFilterFactory() { return new CommandLineReceiveFilterFactory(TextEncoding); }
F:\CodeForGitBlit\SuperSocket\SocketBase\Protocol\CommandLineReceiveFilterFactory.cs
public class CommandLineReceiveFilterFactory : TerminatorReceiveFilterFactory
return m_RequestParser.ParseRequestInfo(m_Encoding.GetString(data, offset, length));
F:\CodeForGitBlit\SuperSocket\SocketBase\Protocol\BasicRequestInfoParser.cs
public class BasicRequestInfoParser : IRequestInfoParser<StringRequestInfo>
public StringRequestInfo ParseRequestInfo(string source) { int pos = source.IndexOf(m_Spliter); string name = string.Empty; string param = string.Empty; if (pos > 0) { name = source.Substring(0, pos); param = source.Substring(pos + 1); } else { name = source; } return new StringRequestInfo(name, param, param.Split(m_ParameterSpliters, StringSplitOptions.RemoveEmptyEntries)); }