SuperSocket 1.6 创建一个简易的报文长度在头部的Socket服务器
我们来做一个头为6位报文总长度,并且长度不包含长度域自身的例子。比如这样的Socket报文000006123456。
添加SuperSocket.Engine,直接使用Nuget搜索SuperSocket.Engine安装即可,依赖项为SuperSocket和log4net。
这里注意,SuperSocket 2.0以后没有SuperSocket.Engine了,直接使用SuperSocket即可,但是由于我这次是在.net framework 4.7的环境下使用,SuperSocket 2.0最低支持.net standard 2.1即只能支持.net core已经.net 5 6了,所以这里没法使用。
创建一个ReceiveFilter。
public class LengthReceiveFilter: FixedHeaderReceiveFilter<StringRequestInfo>
{
public LengthReceiveFilter() : base(6)
{
}
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
{
return int.Parse(Encoding.Default.GetString(header, offset, length));
}
protected override StringRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
{
return new StringRequestInfo("", Encoding.UTF8.GetString(bodyBuffer, offset, length), null);
}
}
这里我们需要重写两个方法,以及调用一下父类的构造方法。
public LengthReceiveFilter() : base(6)这里的6代表头长度为6位。
在protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)方法中,header即为截取到的6位报文头的byte数组,offset是偏移量,length是长度,返回值为报文的总长度。
由于我们报文格式中前六位为数字格式的报文长度,所以我们可以直接用int.Parse(Encoding.Default.GetString(header, offset, length))来获取报文长度,如果长度包含长度本身,那要在-6,这里返回的是报文体的长度,如果返回的长度过长,则会不断的等待后续包。
protected override StringRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)是真正的解析方法,
把我们的报文转换成RequestInfo。这里我们直接用StringRequestInfo,就是把报文简单粗暴的直接转换成字符串。其中header就是我们的报文头的数据,如果这里还需要报文头就从header中拿,bodyBuffer就是我们的报文内容,offset是偏移量,length是长度。
如果我们在GetBodyLengthFromHeader方法中返回的长度比报文体还要长,那么就一直不会走到ResolveRequestInfo这个方法中。
新建一个
MyAppServer继承AppServer
public class MyAppServer : AppServer
{
public MyAppServer() : base(new DefaultReceiveFilterFactory<LengthReceiveFilter,StringRequestInfo>())
{
}
}
这里我们直接用DefaultReceiveFilterFactory这个内置的工厂来绑定我们的Filter。
启动服务器
private void button1_Click(object sender, EventArgs e)
{
AppServer appServer = new MyAppServer();
appServer.NewSessionConnected += session =>
{
};
appServer.NewRequestReceived += (session, info) =>
{
MessageBox.Show(info.Body);
session.Send("hello");
session.Close();
};
if (!appServer.Setup(1234))
{
MessageBox.Show("服务器设置失败");
return;
}
if (!appServer.Start())
{
MessageBox.Show("服务器启动失败");
return;
}
}
我们可以直接new MyAppServer来创建服务器。Setup方法的参数是端口号,我们使用appServer.Setup(1234)即把SocketServer监听的端口号设置为1234,appServer.Start()正式开启服务器。
appServer.NewSessionConnected是有新客户端连接上来的事件,这时候我们可以给客户端发送欢迎信息,或者执行一些其他操作。
appServer.NewRequestReceived是接收到新消息的事件,我们在这里可以拿到RequestInfo,从而获取到对应的信息。并且可以直接通过Send方法来返回消息。
这里需要注意的是如果Send直接使用字符串重载,那么会使用默认的编码格式,如果报文时UTF-8的,那么建议先用Encoding.UTF8.GetBytes转成byte数组,然后用Send的数组重载来发送内容。
关闭服务器
appServer.Stop();
即可关闭服务器。
SuperSocket 1.6 创建一个简易的报文长度在头部的Socket服务器的更多相关文章
- 依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在<依赖注入[4]: 创建一个简易版的DI框架[上篇]> ...
- 依赖注入[4]: 创建一个简易版的DI框架[上篇]
本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章(<控制反转>.<基于IoC的设计模式>和< 依赖注入模式>)从纯理论的角度 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- 使用Python创建一个简易的Web Server
Python 2.x中自带了SimpleHTTPServer模块,到Python3.x中,该模块被合并到了http.server模块中.使用该模块,可以快速创建一个简易的Web服务器. 我们在C:\U ...
- 如何使用Java AWT 创建一个简易计算器
摘要:手把手教你使用 Java AWT 创建一个简易计算器. 本文分享自华为云社区<手把手教你使用 Java AWT 创建一个简易计算器>,作者:海拥 . 关于AWT AWT (抽象窗口工 ...
- 用three.js创建一个简易的天空盒
本文创建的天空盒是用六张图片来创建的.笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用.一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建.另一种则是简单的将纹理作为场景的 ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- Unity创建一个简易的弹簧(弹动)效果
参考文章:http://www.cnblogs.com/SkyD/archive/2008/09/05/1284778.html 主要依据胡克公式F=-k·x.这里k是倔度系数,可以理解为k值越大弹性 ...
- python基础[18]——使用django创建一个简易的博客网站
一.页面实现 index.html base.html post.html header.html footer.html <!-- index.html--> {% extends 'b ...
随机推荐
- Google广告批量投放脚本
该脚本文件是一个转化文件,将编辑的Google投广告模板转化成Google批量投放广告的脚本文件,实现批量投放广告,节省投广时间.PS:要与相应的模板结合使用,投广告模板在本人博客的文件中,可以下载. ...
- python学习-Day19
目录 今日内容详细 正则表达式 开端 概念及相关符号 正则表达式之字符组 正则表达式之特殊符号 正则表达式之量词 小试牛刀 实现手机号码校验功能 复杂正则的编写 校验用户身份证号码 校验邮箱.快递单号 ...
- XCTF练习题---WEB---Cookie
XCTF练习题---WEB---Cookie flag:cyberpeace{dc6a6799546a3e0fbfeacb8650b55ff0} 解题步骤: 1.观察题目,打开场景 2.观察场景内容, ...
- Win10系统链接蓝牙设备
1. 进入控制面板,选择 设备 2. 进入设备界面,删除已有蓝牙,如果蓝牙耳机已经链接其他设备,先断开链接 3. 点击添加蓝牙或其他设备 4. 选择蓝牙,选择你的蓝牙耳机名称
- Linux 30岁,这些年经历了什么?
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 3月19日,Linux基金会在Twitter上发布推文宣布,其小企鹅的标志"Tux& ...
- 干货 | Nginx 配置文件详解
一个执着于技术的公众号 前言 在前面章节中,我们介绍了nginx是什么.如何编译安装nginx及如何彻底卸载nginx软件. 干货|给小白的 Nginx 10分钟入门指南 Nginx编译安装及常用命令 ...
- arts-week9
Algorithm 521. Longest Uncommon Subsequence I - LeetCode Review 如何搭建一个私有的CDN? 大部分情况下,我们使用市场上现有的 CDN ...
- 385. Mini Parser - LeetCode
Question 385. Mini Parser Solution 分析:用NI(count,list)来表示NestedInteger,则解析字符串[123,[456,[789]]]过程如下: # ...
- 好客租房1-React基础目标
学习目标 能够说出React是什么 掌握react的特点 掌握react的基本使用 能够使用react脚手架 学习目录 react概述 react基本使用 react脚手架
- unity---寻路导航
寻路导航 1. 简单的寻路 先搭建出类似下面的结构 将你想作为障碍的物体放入一个空物体中 进入空物体点击Static,仅勾选 Navigation Static 即可 依次点击 Window-> ...