SuperSocket

内置的常用协议实现模版

中文(中国)Toggle Dropdown
v1.6Toggle 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":

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

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

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

public class YourReceiveFilter : TerminatorReceiveFilter<YourRequestInfo>
{//More code
}

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

public class YourReceiveFilterFactory : IReceiveFilterFactory<YourRequestInfo>
{//More code
}

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

CountSpliterReceiveFilter - 固定数量分隔符协议

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

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

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

CountSpliterReceiveFilter<TRequestInfo>
CountSpliterReceiveFilterFactory<TReceiveFilter>
CountSpliterReceiveFilterFactory<TReceiveFilter, TRequestInfo>

FixedSizeReceiveFilter - 固定请求大小的协议

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

class MyReceiveFilter : FixedSizeReceiveFilter<StringRequestInfo>
{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<MyReceiveFilter, StringRequestInfo>()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory){}
}

BeginEndMarkReceiveFilter - 带起止符的协议

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

class MyReceiveFilter : BeginEndMarkReceiveFilter<StringRequestInfo>
{//开始和结束标记也可以是两个或两个以上的字节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<MyReceiveFilter, StringRequestInfo>()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory){}
}

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

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

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

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

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

class MyReceiveFilter : FixedHeaderReceiveFilter<BinaryRequestInfo>
{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<byte> 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 中启用该协议.

  • Prev: 内置的命令行协议
  • Next: 使用 IRequestInfo 和 IReceiveFilter 等等其他对象来实现自定义协议

© 2018 - GetDocs.Net - Hosted by BuyVM

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

内置的常用协议实现模版相关推荐

  1. python operator 多属性排序_又碰到一个非常实用的模块,以后的各种运算就用它了,python内置的常用包。

    在工作中,经常对数据进行各种运算,如要从一个序列中返回一个新的序列,亦或是要对两个数进行比较或者进行加和操作等.如果只是一个简单的运算,怎么都好办.但如果我们面对的是比较复杂的需求时,可能我们更多的是 ...

  2. Cocos2d-x内置的常用层

    为了方便游戏开发者,Cocos2d-x内置了3种特殊的CCLayer,具体如下所示.  CCLayerColor:一个单纯的实心色块. CCLayerGradient:一个色块,但可以设置两种颜色的渐 ...

  3. 内置MCU H323协议的会议录播一体机集成中控音频处理器

    派尼珂Pnioke多功能媒体综合数字录播一体机,集成音视频综合处理器,软件可视化操作界面平台.硬件集成化设计,旨在为用户提供行业一体的解决方案. 应用场景:主要用于多媒体高清会议系统.科技法庭.车载指 ...

  4. 零基础学Python(第二十二章 常用内置函数)

    本套学习内容共计[22]个章节,每个章节都会有对应的从0-1的学习过程详细讲解,希望可以给更多的人提供帮助. 开发环境:[Win10] 开发工具:[Visual Studio 2019] 本章内容为: ...

  5. python 全栈开发,Day51(常用内置对象,函数,伪数组 arguments,关于DOM的事件操作,DOM介绍)...

    昨日内容回顾 1.三种引入方式1.行内js <div onclick = 'add(3,4)'></div>//声明一个函数function add(a,b){}2.内接js& ...

  6. Python生成器的send方法、递推函数、匿名函数及常用内置函数

    1.生成器的send方法 在使用yield方法创建生成器时,不仅可以使用next方法进行取值,还可以通过send方法向生成器的内部传值 1.1 什么是send方法? send方法相当于高级的next方 ...

  7. 前端JavaScript(2) --常用内置对象,函数,伪数组 arguments,关于DOM的事件操作,DOM介绍...

    昨日内容回顾 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...

  8. JSP第四课:用户注册登录设计(内置对象使用)

     一.相关知识:内置对象使用 客户端的浏览器从Web服务器上获得网页,实际上是使用HTTP协议向服务器发送一个请求,服务器在接收到来自客户端浏览器发来的请求后要响应请求.JSP通过request对象获 ...

  9. python函数type的用意_Python内置函数Type()函数一个有趣的用法

    Python内置函数Type()函数一个有趣的用法 今天在网上看到type的一段代码 ,然后查了一下文档,才知道type还有三个参数的用法. 以前只是知道type可以检测对象类型.然后发现了一个有趣的 ...

最新文章

  1. R语言percent函数用百分比表示数值实战
  2. 为什么开发中逐渐抛弃jsp(转)
  3. 对频率论(Frequentist)方法和贝叶斯方法(Bayesian Methods)的一个总结
  4. os.chdir 的作用是什么_为什么宝宝有事都愿意找妈妈?爸爸也要尽到责任才行
  5. (十一)python3 只需3小时带你轻松入门——面向对象
  6. hive 的 left semi join 讲解与left jion的区别
  7. 进程间传递文件描述符--sendmsg,recvmsg(可用)
  8. 全民wa矿小程序源码
  9. 20140419-MCSA 2012 Server R2 IntegrationService
  10. 一元购抽奖号码 thinkphp php
  11. 我的第一篇博文——简单的C/S模型
  12. webstorm2020背景和字体_WebStorm改变字体大小以及更换背景颜色
  13. 计算机修改人类记忆曲线,遗忘曲线——揭秘人类记忆存储的奥秘
  14. 专访容智信息柴亚团:终极愿景是助力天下企业成为数字化孪生组织
  15. 最小环问题(无向图)
  16. 【Three.js入门】纹理加载进度、环境贴图、经纬线映射贴图与高动态范围成像HDR
  17. 安装python3.7后报错No module named ‘ufw‘
  18. 【kubesphere】Deploy to kubernets阶段报错
  19. BNUOJ--19139 PvZ once again
  20. Java实现 蓝桥杯 历届试题 矩阵翻硬币

热门文章

  1. scala hashmap_如何在Scala中将Hashmap转换为Map?
  2. 按频率对元素进行排序
  3. python求素数算法_Python程序最多可计算n个质数(使用不同算法)
  4. C++ 对引用的理解5
  5. 内核ko模块strip使用
  6. 数据结构之自建算法库——链栈
  7. 【Leetcode | 12】342. 4的幂
  8. STL源码剖析面试问题
  9. Java进阶面试资料无偿分享!真香系列
  10. K8S+Docker理论与实践深度集成