博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内置的常用协议实现模版
阅读量:6252 次
发布时间:2019-06-22

本文共 5073 字,大约阅读时间需要 16 分钟。

内置的常用协议实现模版

中文(中国)
Toggle Dropdown
 
v1.6
Toggle Dropdown

关键字: TerminatorReceiveFilter, CountSpliterReceiveFilter, FixedSizeReceiveFilter, BeginEndMarkReceiveFilter, FixedHeaderReceiveFilter

阅读了前面一篇文档之后, 你可能会觉得用 SuperSocket 来实现你的自定义协议并不简单。 为了让这件事变得更容易一些, SuperSocket 提供了一些通用的协议解析工具, 你可以用他们简单而且快速的实现你自己的通信协议:

  • TerminatorReceiveFilter (SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter, SuperSocket.SocketBase)
  • CountSpliterReceiveFilter (SuperSocket.Facility.Protocol.CountSpliterReceiveFilter, SuperSocket.Facility)
  • FixedSizeReceiveFilter (SuperSocket.Facility.Protocol.FixedSizeReceiveFilter, SuperSocket.Facility)
  • BeginEndMarkReceiveFilter (SuperSocket.Facility.Protocol.BeginEndMarkReceiveFilter, SuperSocket.Facility)
  • FixedHeaderReceiveFilter (SuperSocket.Facility.Protocol.FixedHeaderReceiveFilter, SuperSocket.Facility)

TerminatorReceiveFilter - 结束符协议

与命令行协议类似,一些协议用结束符来确定一个请求.

例如, 一个协议使用两个字符 "##" 作为结束符, 于是你可以使用类 "TerminatorReceiveFilterFactory":

/// /// TerminatorProtocolServer/// Each request end with the terminator "##"/// ECHO Your message##/// public class TerminatorProtocolServer : AppServer{    public TerminatorProtocolServer()        : base(new TerminatorReceiveFilterFactory("##"))    {    }}

默认的请求类型是 StringRequestInfo, 你也可以创建自己的请求类型, 不过这样需要你做一点额外的工作:

基于TerminatorReceiveFilter实现你的接收过滤器(ReceiveFilter):

public class YourReceiveFilter : TerminatorReceiveFilter
{ //More code}

实现你的接收过滤器工厂(ReceiveFilterFactory)用于创建接受过滤器实例:

public class YourReceiveFilterFactory : IReceiveFilterFactory
{ //More code}

然后在你的 AppServer 中使用这个接收过滤器工厂(ReceiveFilterFactory).

CountSpliterReceiveFilter - 固定数量分隔符协议

有些协议定义了像这样格式的请求 "#part1#part2#part3#part4#part5#part6#part7#". 每个请求有7个由 '#' 分隔的部分. 这种协议的实现非常简单:

/// /// Your protocol likes like the format below:/// #part1#part2#part3#part4#part5#part6#part7#/// public class CountSpliterAppServer : AppServer{    public CountSpliterAppServer()        : base(new CountSpliterReceiveFilterFactory((byte)'#', 8)) // 7 parts but 8 separators    {    }}

你也可以使用下面的类更深入的定制这种协议:

CountSpliterReceiveFilter
CountSpliterReceiveFilterFactory
CountSpliterReceiveFilterFactory

FixedSizeReceiveFilter - 固定请求大小的协议

在这种协议之中, 所有请求的大小都是相同的。如果你的每个请求都是有9个字符组成的字符串,如"KILL BILL", 你应该做的事就是想如下代码这样实现一个接收过滤器(ReceiveFilter):

class MyReceiveFilter : FixedSizeReceiveFilter
{ public MyReceiveFilter() : base(9) //传入固定的请求大小 { } protected override StringRequestInfo ProcessMatchedRequest(byte[] buffer, int offset, int length, bool toBeCopied) { //TODO: 通过解析到的数据来构造请求实例,并返回 }}

然后在你的 AppServer 类中使用这个接受过滤器 (ReceiveFilter):

public class MyAppServer : AppServer{    public MyAppServer()        : base(new DefaultReceiveFilterFactory
()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory) { }}

BeginEndMarkReceiveFilter - 带起止符的协议

在这类协议的每个请求之中 都有固定的开始和结束标记。例如, 我有个协议,它的所有消息都遵循这种格式 "!xxxxxxxxxxxxxx$"。因此,在这种情况下, "!" 是开始标记, "$" 是结束标记,于是你的接受过滤器可以定义成这样:

class MyReceiveFilter : BeginEndMarkReceiveFilter
{ //开始和结束标记也可以是两个或两个以上的字节 private readonly static byte[] BeginMark = new byte[] { (byte)'!' }; private readonly static byte[] EndMark = new byte[] { (byte)'$' }; public MyReceiveFilter() : base(BeginMark, EndMark) //传入开始标记和结束标记 { } protected override StringRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length) { //TODO: 通过解析到的数据来构造请求实例,并返回 }}

然后在你的 AppServer 类中使用这个接受过滤器 (ReceiveFilter):

public class MyAppServer : AppServer{    public MyAppServer()        : base(new DefaultReceiveFilterFactory
()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory) { }}

FixedHeaderReceiveFilter - 头部格式固定并且包含内容长度的协议

这种协议将一个请求定义为两大部分, 第一部分定义了包含第二部分长度等等基础信息. 我们通常称第一部分为头部.

例如, 我们有一个这样的协议: 头部包含 6 个字节, 前 4 个字节用于存储请求的名字, 后两个字节用于代表请求体的长度:

/// +-------+---+-------------------------------+/// |request| l |                               |/// | name  | e |    request body               |/// |  (4)  | n |                               |/// |       |(2)|                               |/// +-------+---+-------------------------------+

使用 SuperSocket, 你可以非常方便的实现这种协议:

class MyReceiveFilter : FixedHeaderReceiveFilter
{ public MyReceiveFilter() : base(6) { } protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) { return (int)header[offset + 4] * 256 + (int)header[offset + 5]; } protected override BinaryRequestInfo ResolveRequestInfo(ArraySegment
header, byte[] bodyBuffer, int offset, int length) { return new BinaryRequestInfo(Encoding.UTF8.GetString(header.Array, header.Offset, 4), bodyBuffer.CloneRange(offset, length)); }}

你需要基于类FixedHeaderReceiveFilter实现你自己的接收过滤器.

  • 传入父类构造函数的 6 表示头部的长度;
  • 方法"GetBodyLengthFromHeader(...)" 应该根据接收到的头部返回请求体的长度;
  • 方法 ResolveRequestInfo(....)" 应该根据你接收到的请求头部和请求体返回你的请求类型的实例.

然后你就可以使用接收或者自己定义的接收过滤器工厂来在 SuperSocket 中启用该协议.

 

© 2018 - GetDocs.Net - 

转载于:https://www.cnblogs.com/liuslayer/p/8624336.html

你可能感兴趣的文章
java安全证书配置
查看>>
使用erlang 建立一个自动化的灌溉系统(1)准备工作
查看>>
python 调用aiohttp
查看>>
mysql 案例~ mysql故障恢复
查看>>
Spring Boot中使用MyBatis注解配置详解
查看>>
MatLab实现FFT与功率谱
查看>>
答《漫话ID》中的疑问:UniqueID和ClientID的来源
查看>>
【转】Asp.net控件开发学习笔记整理篇 - 服务器控件生命周期
查看>>
Linux下的shell编程(一)BY 四喜三顺
查看>>
javascript一些小技巧
查看>>
I00024 出钱买羽
查看>>
linux下文件的一些文件颜色的含义
查看>>
websotrm注册码
查看>>
迭代器(Iterable)和for..in..的三种协议
查看>>
判断浏览器是否为顶层窗口
查看>>
数据结构化与保存
查看>>
跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
查看>>
服务器设计笔记(3)-----消息队列
查看>>
poj 1797 Heavy Transportation(最短路径Dijkdtra)
查看>>
基于WinDbg的内存泄漏分析
查看>>