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 ...
随机推荐
- MySQL8自增主键变化
MySQL8自增主键变化 醉后不知天在水,满船清梦压星河. 一.简述 MySQL版本从5直接大跃进到8,相信MySQL8一定会有很多令人意想不到的改进,如果不想只会CRUD可以看看. 比如系统表引擎的 ...
- 从零开始,开发一个 Web Office 套件(15):拖动边框,平移编辑器
这是一个系列博客,最终目的是要做一个基于 HTML Canvas 的.类似于微软 Office 的 Web Office 套件(包括:文档.表格.幻灯片--等等). 博客园:<从零开始, 开发一 ...
- JDK内置锁深入探究
一.序言 本文讲述仅针对 JVM 层次的内置锁,不涉及分布式锁. 锁有多种分类形式,比如公平锁与非公平锁.可重入锁与非重入锁.独享锁与共享锁.乐观锁与悲观锁.互斥锁与读写锁.自旋锁.分段锁和偏向锁/轻 ...
- XCTF练习题---MISC---Erik-Baleog-and-Olaf
XCTF练习题---MISC---Erik-Baleog-and-Olaf flag:flag{#justdiffit} 解题步骤: 1.观察题目,下载附件 2.拿到手以后发现是一个没有后缀名的文件, ...
- XCTF练习题---MISC---pure-color
XCTF练习题---MISC---pure-color flag:flag{true_steganographers_doesnt_need_any_tools} 解题步骤: 1.观察题目,下载附件 ...
- 2022 Java生态系统报告:Java 11超Java 8、Oracle在缩水、Amazon在崛起!
近日,New Relic发布了最新的2022 Java生态系统报告,这份报告可以帮助我们深入的了解Java体系的最新使用情况,下面就一起来看看2022年,Java发展的怎么样了,还是Java 8 YY ...
- RESTFul是一种风格
只要符合RESTFul风格的,都可以叫做使用了RESTFul架构,一般的网站里传数据,都是用的?a=1&b=2...如果是RESTFul风格的话,就会是/a/1/b/2..类似于这样的方式来传 ...
- 用简单的 Node.js 后台程序浅析 HTTP 请求与响应
用简单的 Node.js 后台程序浅析 HTTP 请求与响应 本文写于 2020 年 1 月 18 日 我们来看两种方式发送 HTTP 请求,一种呢,是命令行的 curl 命令:一种呢是直接在浏览器的 ...
- 软件项目管理 ——1.2.PMBOK与软件项目管理知识体系
软件项目管理 --1.2.PMBOK与软件项目管理知识体系 归档于软件项目管理初级学习路线 第一章 软件项目管理基本概念 <初级学习路线合集 > @ 目录 软件项目管理 --1.2.PMB ...
- 好客租房40-react组件基础综合案例-案例需求分析
实现 案例的数据 渲染评论列表 有评论 没有评论 暂无评论 获取评论信息 包括评论人和受控组件 发表评论 更新评论 //导入react import React from 'react' import ...