SuperSocket 协议

news2024/9/25 20:40:33

1、通过之前的学习,我们知道在SuperSocket中,客户端向服务器发送数据时需要以回车换行符“\r\n”结尾服务端才能够识别。这是因为SuperSocket的默认协议CommandLineProtocol(命令行协议)要求所致。SuperSocket还有以下常用的协议(我按照翻译的……)。

1.1、CommandLineProtocol:命令行协议,要求以回车换行符“\r\n”结尾。

1.2、TerminatorReceiveFilter:结束符协议。

1.3、CountSpliterReceiveFilter:固定数量分隔符协议。

1.4、FixedSizeReceiveFilter:固定请求大小协议。

1.5、BeginEndMarkReceiveFilter:起止标记协议。

1.6、FixedHeaderReceiveFilter:固定头部协议。

2、在之前的学习中,我们通过使用StringRequestInfo来解析客户端发送的数据。StringRequestIfo有三个属性,

2.1、Key:协议中的命令字段,是发送数据用空格分隔的第一个字符串,例如我们之前使用的SocketCommand1.cs,客服端想要调用SocketCommand1.cs中的ExecuteCommand方法需要先发送"SocketCommand1"字符串作为命令。用空格与后面的内容隔开。

2.2、Body:命令的参数部分,以SocketCommand1举例,客户端发送"SocketCommand1 123 321",那么Body部分就是"123 321"。

2.3、Parameters:命令的参数组,以SocketCommand1举例,客户端发送"SocketCommand1 123 321",那么Parameters部分就是["123","321"]。

2.4、客户发送的数据key与参数直接默认是以空格隔开。

3、除了StringBinaryRequestInfo以外,SuperSocket还支持BinaryRequestInfo用于二进制传输。

4、客户端向服务器传输的命令和参数可以使用其它分隔符进行分隔,如下面代码使用“,”和“:”进行分隔。

        public SocketServer() : base(
            new CommandLineReceiveFilterFactory(Encoding.Default, new BasicRequestInfoParser(",", ":")))
        {

        }

完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using SuperSocket.SocketBase.Protocol;

namespace ConsoleApp1.Config
{
    /// <summary>
    /// 重写AppServer类
    /// </summary>
    public class SocketServer:AppServer<SocketSession>
    {
        public SocketServer() : base(
            new CommandLineReceiveFilterFactory(Encoding.Default, new BasicRequestInfoParser(",", ":")))
        {

        }
        /// <summary>
        /// 重写启动SocketServer
        /// </summary>
        /// <param name="rootConfig"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
        {
            Console.WriteLine("启动SocketServer");
            return base.Setup(rootConfig, config);
        }
        /// <summary>
        /// 重写服务已启动
        /// </summary>
        protected override void OnStarted()
        {
            Console.WriteLine("服务已开始");
            base.OnStarted();
        }
        /// <summary>
        /// 重写服务已停止
        /// </summary>
        protected override void OnStopped()
        {
            Console.WriteLine("服务已停止");
            base.OnStopped();
        }
        /// <summary>
        /// 重写新的连接建立
        /// </summary>
        /// <param name="session"></param>
        protected override void OnNewSessionConnected(SocketSession session)
        {
            base.OnNewSessionConnected(session);
            Console.WriteLine("新客户端接入,IP地址为:"+session.RemoteEndPoint.Address.ToString());
            session.Send("Welcome");
        }
        /// <summary>
        /// 重写客户端连接关闭
        /// </summary>
        /// <param name="session"></param>
        /// <param name="reason"></param>
        protected override void OnSessionClosed(SocketSession session, CloseReason reason)
        {
            base.OnSessionClosed(session, reason);
            Console.WriteLine("客户端断开,IP地址为:" + session.RemoteEndPoint.Address.ToString());
        }
    }
}

5、TerminatorReceiveFilter结束符协议,修改方法。

 

5.1、 新建TerminatorProtocolSession.cs。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;

namespace ConsoleApp1
{
    /// <summary>
    /// 自定义结束符类TerminatorProtocolSession
    /// </summary>
    public class TerminatorProtocolSession:AppSession<TerminatorProtocolSession>
    {
        /// <summary>
        /// 重写发送
        /// </summary>
        /// <param name="message"></param>
        public override void Send(string message)
        {
            Console.WriteLine("发送消息:" + message);
            base.Send(message);
        }
        /// <summary>
        /// 重写客户端建立连接
        /// </summary>
        protected override void OnSessionStarted()
        {
            Console.WriteLine("客户端IP地址:" + this.LocalEndPoint.Address.ToString());
            base.OnSessionStarted();
        }
        /// <summary>
        /// 重写客户端断开连接
        /// </summary>
        /// <param name="reason"></param>
        protected override void OnSessionClosed(CloseReason reason)
        {
            base.OnSessionClosed(reason);
        }
        /// <summary>
        /// 重写未知请求
        /// </summary>
        /// <param name="requestInfo"></param>
        protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
        {
            Console.WriteLine("遇到位置请求Key:" + requestInfo.Key + "  Body:" + requestInfo.Body);
            base.HandleUnknownRequest(requestInfo);
        }
        /// <summary>
        /// 重写捕获异常
        /// </summary>
        /// <param name="e"></param>
        protected override void HandleException(Exception e)
        {
            Console.WriteLine("error:{0}", e.Message);
            this.Send("error:{0}", e.Message);
            base.HandleException(e);
        }
    }
}

5.2、修改SocketServer.cs代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using SuperSocket.Common;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using SuperSocket.SocketBase.Protocol;
using SuperSocket.SocketEngine;

namespace ConsoleApp1.Config
{
    /// <summary>
    /// 重写AppServer类
    /// </summary>
    public class SocketServer:AppServer<TerminatorProtocolSession>
    {
        public SocketServer() : base(new TerminatorReceiveFilterFactory("###"))
        {

        }
        /// <summary>
        /// 重写启动SocketServer
        /// </summary>
        /// <param name="rootConfig"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
        {
            Console.WriteLine("启动SocketServer");
            return base.Setup(rootConfig, config);
        }
        /// <summary>
        /// 重写服务已启动
        /// </summary>
        protected override void OnStarted()
        {
            Console.WriteLine("服务已开始");
            base.OnStarted();
        }
        /// <summary>
        /// 重写服务已停止
        /// </summary>
        protected override void OnStopped()
        {
            Console.WriteLine("服务已停止");
            base.OnStopped();
        }
        /// <summary>
        /// 重写新的连接建立
        /// </summary>
        /// <param name="session"></param>
        protected override void OnNewSessionConnected(TerminatorProtocolSession session)
        {
            base.OnNewSessionConnected(session);
            Console.WriteLine("新客户端接入,IP地址为:" + session.RemoteEndPoint.Address.ToString());
            session.Send("Welcome");
        }
        /// <summary>
        /// 重写客户端连接关闭
        /// </summary>
        /// <param name="session"></param>
        /// <param name="reason"></param>
        protected override void OnSessionClosed(TerminatorProtocolSession session, CloseReason reason)
        {
            base.OnSessionClosed(session, reason);
            Console.WriteLine("客户端断开,IP地址为:" + session.RemoteEndPoint.Address.ToString());
        }

        / <summary>
        / 重写新的连接建立
        / </summary>
        / <param name="session"></param>
        //protected override void OnNewSessionConnected(SocketSession session)
        //{
        //    base.OnNewSessionConnected(session);
        //    Console.WriteLine("新客户端接入,IP地址为:"+session.RemoteEndPoint.Address.ToString());
        //    session.Send("Welcome");
        //}
        / <summary>
        / 重写客户端连接关闭
        / </summary>
        / <param name="session"></param>
        / <param name="reason"></param>
        //protected override void OnSessionClosed(SocketSession session, CloseReason reason)
        //{
        //    base.OnSessionClosed(session, reason);
        //    Console.WriteLine("客户端断开,IP地址为:" + session.RemoteEndPoint.Address.ToString());
        //}
    }
}

5.3、修改SocketCommand1.cs和SocketCommand2.cs代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;

namespace ConsoleApp1.Config
{
    /// <summary>
    /// 自定义SocketCommand1
    /// </summary>
    public class SocketCommand1 : CommandBase<TerminatorProtocolSession, StringRequestInfo>
    {
        public override void ExecuteCommand(TerminatorProtocolSession session, StringRequestInfo requestInfo)
        {
            session.Send("1");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;

namespace ConsoleApp1.Config
{
    /// <summary>
    /// 自定义Command1
    /// </summary>
    public class SocketCommand2 : CommandBase<TerminatorProtocolSession, StringRequestInfo>
    {
        public override void ExecuteCommand(TerminatorProtocolSession session, StringRequestInfo requestInfo)
        {
            session.Send(string.Format("{0} {1}","1","123"));
        }
    }
}

5.4、项目结构如下。

5.5、 App.config文件内容如下。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

	<configSections>
		<!--log 日志记录-->
		<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
		<!--SocketEngine-->
		<section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/>
	</configSections>


	<!--服务信息描述,在window服务模式下的名称标识-->
	<appSettings>
		<add key="ServiceName" value="ConsoleApp1"/>
		<add key="ServiceDescription" value="bjxingch"/>
	</appSettings>

	<!--SuperSocket服务配置信息 serverType是项目的服务如我自定义的Socketserver-->
	<superSocket>
		<servers>
			<server name="ConsoleApp1"
			        textEncoding="gb2312"
			        serverType="ConsoleApp1.Config.SocketServer,ConsoleApp1"
			        ip="Any"
			        port="2024"
			        maxConnectionNumber="100"/>
			<!--
				name:实例名称
				textEncoding:编码方式"gb2312","utf-8" 默认是acii
				serverType:需要注意,否则无法启动Server
				ip:监听ip
				port:端口号
				maxConnectionNumber:最大连接数
			-->
		</servers>
	</superSocket>


	<startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
</configuration>

6、Demo下载路径如下。

https://download.csdn.net/download/xingchengaiwei/89316001

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1700915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

事务报错没有显示回滚导致DDL阻塞引发的问题

在业务开发过程中&#xff0c;显示的开启事务并且在事务处理过程中对不同的情况进行显示的COMMIT或ROLLBACK&#xff0c;这是一个完整数据库事务处理的闭环过程。 这种在应用开发逻辑层面去handle的事务执行的结果&#xff0c;既确保了事务操作的数据完整性&#xff0c;又遵循了…

ROS2入门21讲__第21讲__ROS2应用与进阶攻略

资源汇总 常用框架 自主导航 比如移动机器人基本都会具备的自主导航功能&#xff0c;ROS2提供了完整的自主导航系统框架和各种实现好的算法&#xff0c;即便我们不开发任何代码&#xff0c;也可以在自己的机器人上&#xff0c;使用这套系统&#xff0c;快速实现自主导航的基本…

X-CSV-Reader:一个使用Rust实现CSV命令行读取器

&#x1f388;效果演示 ⚡️快速上手 依赖导入&#xff1a; cargo add csv读取实现&#xff1a; use std::error::Error; use std::fs::File; use std::path::Path;fn read_csv<P: AsRef<Path>>(filename: P) -> Result<(), Box<dyn Error>> {le…

40岁的戴尔在AI时代翻红了

戴尔公司股价创历史新高&#xff0c;市值达1138亿美元&#xff0c;涨幅110%。戴尔向AI押注多年&#xff0c;收购企业转型&#xff0c;成为数据基础设施厂商。AI服务器销售增长&#xff0c;分析师看好戴尔未来发展。 5月24日美股收盘&#xff0c;很多人可能不太关注的戴尔公司股…

华为OD机试【计算最接近的数】(java)(100分)

1、题目描述 给定一个数组X和正整数K&#xff0c;请找出使表达式X[i] - X[i1] … - X[i K 1]&#xff0c;结果最接近于数组中位数的下标i&#xff0c;如果有多个i满足条件&#xff0c;请返回最大的i。 其中&#xff0c;数组中位数&#xff1a;长度为N的数组&#xff0c;按照元…

MP3文件本地存储与下载指南

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、建立存储文件夹 三、获取MP3文件URL并下载 四、优化下载过程 五、总结与…

韩愈,文起八代之衰的儒学巨匠

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 韩愈&#xff0c;字退之&#xff0c;生于唐代宗大历三年&#xff08;公元768年&#xff09;&#xff0c;卒于唐穆宗长庆四年&#xff08;公元82…

Activiti7_使用

Activiti7_使用 一、Activiti7二、绘制工作流三、通过代码部署流程&#xff0c;再对流程进行实例化&#xff0c;完整运行一遍流程即可四、在springbooot中使用 一、Activiti7 为了实现后端的咨询流转功能&#xff0c;学习Activiti7&#xff0c;记录下使用的过程及遇到的问题 二…

力扣 第 399 场周赛 解题报告 | 珂学家 | 调和级数 + 分块DP

前言 T1. 优质数对的总数 I 题型: 签到 class Solution:def numberOfPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:res 0for v1 in nums1:for v2 in nums2:if v1 % (v2 * k) 0:res 1return resT2. 压缩字符串 III 思路: 模拟 感觉引入一个栈&…

通用代码生成器应用场景三,遗留项目反向工程

通用代码生成器应用场景三&#xff0c;遗留项目反向工程 如果您有一个遗留项目&#xff0c;要重新开发&#xff0c;或者源代码遗失&#xff0c;或者需要重新开发&#xff0c;但是希望复用原来的数据&#xff0c;并加快开发。 如果您的项目是通用代码生成器生成的&#xff0c;…

【量算分析工具-概述】GeoServer改造Springboot番外系列三

背景概述 GIS公司做软件产品&#xff0c;往往绕不开的是量算分析工具的开发和使用。例如做的比较好的火星科技的mars3d产品&#xff0c;如下图&#xff0c;但是往往这些工具都是利用Cesium框架进行前端计算的实现的&#xff0c;网上关于这些量算工具算法原理的文章少之又少&…

石英晶体谐振器的频率与电阻温度特性及其影响因素

石英晶体谐振器是一种常用的电子元件&#xff0c;其具有精确的谐振频率&#xff0c;广泛应用于各种电子设备中&#xff0c;如时钟、频率发生器、滤波器等。石英晶体谐振器的频率和电阻温度特性是评价其性能的重要参数。 1. 频率温度特性&#xff1a; 石英晶体谐振器的频率随温…

身为UI设计老鸟,不学点3D,好像要被潮流抛弃啦,卷起来吧。

当前3D原则在UI设计中运用的越来越多&#xff0c;在UI设计中&#xff0c;使用3D元素可以为界面带来以下几个价值&#xff1a; 增强视觉冲击力&#xff1a;3D元素可以通过立体感和逼真的效果&#xff0c;为界面增添视觉冲击力&#xff0c;使得设计更加生动、吸引人&#xff0c;并…

mac电脑用n切换node版本

一、安装 node版本管理工具 “n” sudo npm install -g n二、检查安装成功&#xff1a; n --version三、查看依赖包的所有版本号 比如: npm view webpack versions --json npm view 依赖包名 versions --json四、安装你需要的版本的node sudo n <node版本号> // 例如…

<iframe>标签的使用

前言&#xff1a; 最近做项目需要使用到腾讯位置服务&#xff08;这个之后分享&#xff09;&#xff0c;其中用到了一个之前一直没用到的标签&#xff1a;&#xff1c;iframe&#xff1e;&#xff0c;一时居然不知道这个是干什么用的。今天分享一下。 下面这段代码是我用来测试…

开发者为什么需要“不良代码”

“从未犯过错误的人也从未有过新发现。” — 塞缪尔斯迈尔斯 想象一下场景&#xff1a;苏格兰&#xff0c;1928年。可能在下雨&#xff0c;一位科学家不小心让他的培养皿被霉菌污染了&#xff0c;他并不知道这个错误最终将拯救数百万人的生命&#xff0c;这项伟大的发现就是青…

了解Hive 工作原理:Hive 是如何工作的?

一、概念 1、Hive Apache Hive 是一个分布式的容错数据仓库系统&#xff0c;可实现大规模分析和便于使用 SQL 读取、写入和管理驻留在分布式存储中的PB级数据。 Hive是建立在Hadoop之上的数据仓库框架&#xff0c;它提供了一种类SQL的查询语言—HiveQL&#xff0c;使得熟悉S…

kettle 读取记事本文件给java组件处理

kettle9.4 用到两个组件 文本文件输入 文件内容如下 文本文件输入---文件 文本文件输入---内容 注意事项&#xff1a;分隔符这里&#xff0c;我一直没注意&#xff0c;导致不管怎么读数据都读不到&#xff1b;可以用换行符&#xff0c;可以用其他的&#xff0c;视情况而定&…

[idea/git] 如何把多模块项目提交到一个仓库

一、问题 我使用idea创建项目&#xff0c;依次创建module进行开发&#xff0c;开发完毕之后&#xff0c;在github上创建仓库&#xff0c;配置后发现&#xff0c;在idea里点击提交时&#xff0c;每个模块各自记录commit&#xff0c;并且每个模块都需要配置origin地址。 二、解…

【数据结构】二叉树和堆

文章目录 一、 什么是二叉树二、 二叉树的存储结构顺序存储视图 三、 堆堆的结构及概念大堆和小堆 四、 建堆五、 堆排序六、 topk问题 一、 什么是二叉树 二叉树&#xff0c;作为一种重要的数据结构&#xff0c;由节点组成&#xff0c;每个节点可以有两个子节点&#xff0c;通…