SuperSocket 1.4系列文档(8) 自定义协议

Socket里面的协议解析是Socket通讯程序设计中最复杂的地方,如果你的应用层协议设计或实现不佳,Socket通讯中常见的粘包,分包就难以避免。SuperSocket内置了命令行格式的协议CommandLineProtocol,如果你的用用使用了其它格式的协议,你就必须自行实现自定义协议CustomProtocol。

实现自定义协议

实现自定义协议需要实现ICustomProtocol的Protocol类,和一个实现ICommandReader接口的CommandReader类。

public interface ICustomProtocol<TCommandInfo>
    where TCommandInfo : ICommandInfo
{
    ICommandReader<TCommandInfo> CreateCommandReader(IAppServer appServer);
}

实现ICustomProtocol需要一个实现ICommandInfo的类TCommandInfo来作为泛型参数,类应包含你的协议中每个命令/包的基本数据结构。实现CreateCommandReader方法只需根据appServer来实例化你的CommandReader, 下面就来讲讲CommandReader。

public interface ICommandReader<TCommandInfo>
        where TCommandInfo : ICommandInfo
{
    IAppServer AppServer { get; }
 
    TCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left);
 
    int LeftBufferSize { get; }
 
    ICommandReader<TCommandInfo> NextCommandReader { get; }
}

上面是你要实现的ICommandReader接口。

IAppServer AppServer { get; } :

      返回当前CommandReader运行于的AppServer;

int LeftBufferSize { get; }:

      返回当前CommandReader所缓存数据的大小;

ICommandReader<TCommandInfo> NextCommandReader { get; } :

       指定下轮数据接收到时所使用的CommandReader实例, 不设则使用当前CommandReader实例;

TCommandInfo FindCommandInfo(IAppSession session, byte[] readBuffer, int offset, int length, bool isReusableBuffer, out int left);

      FindCommandInfo方法是CommandReader要实现的核心方法,各个参数的解释如下:

             IAppSession session– Socket所属的AppSession

             byte[] readBuffer - 接收缓冲区

             int offset – 本次接收到的数据在整个接收缓冲区的位移

             int length – 本次接收到的数据的长度

             bool isReusableBuffer – 表明接收缓冲区是否会在下次接受中被重复利用,如果是,你的代码就不能将readerBuffer这个缓冲区直接用于CommandReader缓存

             out int left - 未解析的本次接收数据的长度

             返回值TCommandInfo -  返回在缓冲区内找到协议命令数据,如果未找到,返回null。SuperSocket引擎会根据返回值的Key属性来找到相应的命令来执行。如Key为"ECHO", 名为ECHO的命令将会被执行,此CommandInfo将会是这个命令执行的参数。

 

使用自定义协议

使用自定义协议的方法很简单,只需在你的AppServer里,调用基类构造方法时将CustomProtocol实例传进去:

class CustomProtocolServer : AppServer<CustomProtocolSession, BinaryCommandInfo>
{
    public CustomProtocolServer()
        : base(new MyCustomProtocol())
    {
 
    }
}

注意AppServer所使用的泛型参数TCommandInfo应于CustomProtocol中的泛型参数TCommandInfo相同。

更详细的示例请参考SuperSocket源代码中QuickStart目录中的GPSSocketServer和CustomProtocol项目。

你可能感兴趣的:(socket)