首页 > 编程语言 >C#-网络通讯框架(一)-HPSocket

C#-网络通讯框架(一)-HPSocket

时间:2023-06-13 09:56:40浏览次数:37  
标签:HPSocket using C# 适配器 网络通讯 包头 长度 接收 构造函数

一、简介

这里加一张图片

 

二、基础使用

这里加一张图片

1、TCP

 

2、UDP

三、与线程池一起使用(TCP)

 

四、HPSocket扩展Easy组件(部分)

  HPSocket.Net目前提供6个Easy组件和2个WebSocket组件

  • ITcpPortForwarding
  • IHttpEasyServer
  • IHttpsEasyServer
  • IHttpEasyAgent
  • IHttpsEasyAgent
  • IHttpEasyClient
  • IHttpsEasyClient
  • IWebSocketServer
  • IWebSocketAgent
  • ITcpServer<TRequestBodyType>
  • ITcpClient<TRequestBodyType>
  • ITcpAgent<TRequestBodyType>
  • ISslServer<TRequestBodyType>
  • ISslClient<TRequestBodyType>
  • ISslAgent<TRequestBodyType>
  • AsyncQueue

1、TCP端口转发(ITcpPortForwarding)

 

2、IHttpEasyServer与IHttpEasyClient

 

3、IHttpEasyAgent

 

4、数据接收适配器组件-BinaryDataReceiveAdapter

  数据接收适配器组比HP-Socket的Pack组件更加灵活。

  4种适配模式: 固定包头数据接收适配器、定长包数据接收适配器、结束符数据接收适配器、区间数据接收适配器。

(1)FixedHeaderDataReceiveAdapter固定包头数据接收适配器

使用场景:数据包的包头长度固定且包头含包体长度。

示例:前4字节标识包体长度(小端字节序)。0x00000003表示包体长度为3字节{ 0x61, 0x62 0x63 }为包体。

{ 0x03, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63 }

FixedHeaderDataReceiveAdapter专为这种结构设计

using System;
using System.Text;
using HPSocket.Adapter;
using Models;
using Newtonsoft.Json;

namespace TcpServerTestEchoAdapter.DataReceiveAdapter
{
    /// <summary>
    /// 固定包头数据接收适配器
    /// ① 子类继承FixedHeaderDataReceiveAdapter;
    /// ② 在自身的构造函数中调用父类构造函数,传入包头长度和最大允许的封包长度; 
    /// ③ 覆盖GetBodySize()方法, 其参数header的长度为构造函数中指定的包头长度, 需用户解析这个参数, 返回实际的body长度 
    /// ④ 覆盖ParseRequestBody()方法, 将当前的bytes反序列化为泛型类型(<TRequestBodyType>)对象
    /// </summary>
    public class PacketDataReceiveAdapter : FixedHeaderDataReceiveAdapter<Packet>
    {
        /// <summary>
        /// 调用父类构造函数,指定固定包头的长度及最大封包长度
        /// </summary>
        public PacketDataReceiveAdapter()
            : base(
                headerSize: 4,        // 这里指定4字节包头
                maxPacketSize: 0x1000 // 这里指定最大封包长度不能超过4K
                )
        {

        }

        /// <summary>
        /// 获取请求体长度
        /// <remarks>子类必须覆盖此方法</remarks>
        /// </summary>
        /// <param name="header">包头,header的长度是构造函数里指定的长度,当接收到了指定长度的包头再调用此方法</param>
        /// <returns>返回包体长度</returns>
        protected override int GetBodySize(byte[] header)
        {
            // 根据业务场景来适配字节序, 两端字节序要保持一致

            // 如果当前环境不是小端字节序
            if (!BitConverter.IsLittleEndian)
            {
                // 转换为小端字节序
                Array.Reverse(header);
            }

            // 因为包头是4字节,所以直接转int并返回
            return BitConverter.ToInt32(header, 0);
        }

        /// <summary>
        /// 解析请求体
        /// <remarks>子类必须覆盖此方法</remarks>
        /// </summary>
        /// <param name="header">包头</param>
        /// <param name="data">包体</param>
        /// <returns></returns>
        protected override Packet ParseRequestBody(byte[] header, byte[] data)
        {
            // 将data反序列化为对象
            // 这里是Packet类的对象
            return JsonConvert.DeserializeObject<Packet>(Encoding.UTF8.GetString(data));
        }
    }
}

(2)FixedSizeDataReceiveAdapter定长包数据接收适配器

包长度固定,每个包都是同样大小,使用这种适配器。

FixedSizeDataReceiveAdapter专为这种结构设计

using HPSocket.Adapter;

namespace TcpServerTestEchoAdapter.DataReceiveAdapter
{
    /// <summary>
    /// 定长包数据接收适配器
    /// </summary>
    public class BinaryDataReceiveAdapter : FixedSizeDataReceiveAdapter<byte[]>
    {
        /// <summary>
        /// 调用父类构造函数,指定定长包长度
        /// </summary>
        public BinaryDataReceiveAdapter()
            : base(
                packetSize: 1024 // 定长包包长1K字节
            )
        {
        }

        /// <summary>
        /// 解析请求体
        /// <remarks>子类必须覆盖此方法</remarks>
        /// </summary>
        /// <param name="data">父类处理好的定长数据</param>
        /// <returns></returns>
        protected override byte[] ParseRequestBody(byte[] data)
        {
            // 因为继承自FixedSizeDataReceiveAdapter<byte[]>,所以这里直接返回了,如果是其他类型请做完转换工作再返回
            return data;
        }
    }
}

(3)TerminatorDataReceiveAdapter结束符数据接收适配器

包头无特征, 包尾使用特定标志作为结束符,使用这种适配器

示例:下面这种包结构以\r\n结尾

hello world 1\r\n
hello world 2\r\n
hello world 3\r\n

TerminatorDataReceiveAdapter专为这种结构设计

using System.Text;
using HPSocket.Adapter;

namespace TcpServerTestEchoAdapter.DataReceiveAdapter
{
    /// <summary>
    /// 结束符数据接收适配器
    /// </summary>
    public class TextDataReceiveAdapter : TerminatorDataReceiveAdapter<string>
    {
        /// <summary>
        /// 调用父类构造函数,指定结束符
        /// </summary>
        public TextDataReceiveAdapter()
            : base(
                terminator: Encoding.UTF8.GetBytes("\r\n") // 指定结束符为\r\n,也就是说每条数据以\r\n结尾,注意编码问题,要两端保持一致
                )
        {
        }

        /// <summary>
        /// 解析请求体
        /// <remarks>子类必须覆盖此方法</remarks>
        /// </summary>
        /// <param name="data">父类已经处理好的不含结束符的数据</param>
        /// <returns></returns>
        protected override string ParseRequestBody(byte[] data)
        {
            // 转换成请求对象, 注意字符编码,要两端保持一致
            return Encoding.UTF8.GetString(data);
        }
    }
}

(4)BetweenAndDataReceiveAdapter区间数据接收适配器

示例:数据包头以某特征符号开始,包尾以其它某特征符号结束

##hello world!## // ##开头,##结尾
或
##hello world!|| // ##开头,||结尾
或
**hello world!|##| // **开头,|##|结尾

BetweenAndDataReceiveAdapter专为这种结构设计

using System.Text;
using HPSocket.Adapter;

namespace TcpServerTestEchoAdapter.DataReceiveAdapter
{
    /// <summary>
    /// 区间数据接收适配器
    /// </summary>
    public class HeadTailDataReceiveAdapter : BetweenAndDataReceiveAdapter<string>
    {
        /// <summary>
        /// 调用父类构造函数,指定区间开始和结束特征字符
        /// </summary>
        public HeadTailDataReceiveAdapter() 
            : base( // 例如数据格式是"#*123456*#",其中以#*开头,以*#结尾,中间123456部分是真实数据
                start : Encoding.UTF8.GetBytes("#*"), // 区间起始标志,这里以#*开始,注意编码问题,要两端保持一致
                end : Encoding.UTF8.GetBytes("*#")  // 区间结束标志,这里以*#结束,注意编码问题,要两端保持一致
                )
        {
        }

        /// <summary>
        /// 解析请求体
        /// <remarks>子类必须覆盖此方法</remarks>
        /// </summary>
        /// <param name="data">父类已处理好的不含区间起始标识符的数据</param>
        /// <returns></returns>
        protected override string ParseRequestBody(byte[] data)
        {
            // 转换成请求对象,注意编码问题,要两端保持一致
            return Encoding.UTF8.GetString(data);
        }
    }
}

标签:HPSocket,using,C#,适配器,网络通讯,包头,长度,接收,构造函数
From: https://www.cnblogs.com/qq2806933146xiaobai/p/17476671.html

相关文章

  • SpringCloudAlibaba
    一、SpringCloudAlibaba功能组件?Sentinel:流量控制,熔断降级,系统负载保护等方面。Nacos:注册中心,配置管理中心。RocketMq:分布式消息系统。Dubbo:java的RPC框架。Seata:分布式事务解决方案。AlibabaCloudOSS:阿里云对象存储服务。AlibabaCloudSchedulerX:分布式任务调度产品......
  • Camunda 自定义模型图后 流程节点叠在一起怎么查看
    简单写一下 后面详细补充   根据这个sql语句可以把乱码的数据转码过来SELECTcast(BYTES_ASCHAR)ASBYTES_FROM`act_ge_bytearray`WHEREID_='e4e532d0-c146-11ec-b630-18f22c5016b2'; 把转码后的xml放到CamundaModeler客户端编辑器里面去  ......
  • 函数exit,参数 EXIT_FAILURE,参数EXIT_SUCCESS
    1、函数:exit()所在头文件:stdlib.h功能:关闭所有文件,终止正在执行的进程exit(0)表示正常退出exit(x)都表示异常退出,这个x是返回给操作系统的,以供其他程序使用return和exit:无论在哪里使用main都会终止程序,return只是将控制权交给递归的前一级。return和exit的区别......
  • mybaits-plugs 连接orcale自动生成
    mybaits-plugs连接orcale自动生成calorca  20200516shmybatis-plugs是对mybatis框架进一步封装,今天尝试使用mybatis-plugs的逆向工程连接orcale/mysql数据库生成实体类以及dao1、遇到的问题有连接数据的时候抱错,拒绝连接一定要仔细检查orcalsid服务id是否正......
  • [转]C#---特性与反射
    C#---特性与反射 所有.NET支持的语言编写出来的程序,在对应的编译器编译之后,会先产出程序集,其主要内容是中间语言IL和元数据。之后,JIT再将IL翻译为机器码(不同机器实现方式不同)。IL使得跨平台成为可能,并且统一了各个框架语言编译之后的形式,使得框架实现的代价......
  • [ABC305C] Snuke the Cookie Picker题解
    题目大意有一个\(H\timesW\)的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标。(.表示空白,#表示矩形内的点)解析观察我们可以发现,每一矩形内的个点上下左右至少会有两个是#。如图:而每一个在矩形外的点上下左右最多只有一个#。所以我们只需要找的一个.的上......
  • [ABC305D] Sleep Log题解
    题目大意给\(N\)个时刻:当\(i\)为奇数时,\(A_i\)表示刚刚起床的时刻。当\(i\)为偶数时,\(A_i\)表示开始睡觉的时刻。有\(Q\)次询问,每次求在\([l,r]\)区间内睡了多长时间。分析首先我们要考虑处理边界情况。每一次二分查找第一个大于等于\(l\)和\(r\)的时刻......
  • 安洵杯SYCCTF2023 writeup
    一、MISC1.sudoku_easy简单的数独交互,几个小注意点,每次发送level之后sleep5秒才会返回题目将形如---------------------800103720023840650410006008300001062000052407072060090160000375205019846000030000---------------------转换成二维数组进行解数独......
  • ceshi
       ......
  • Unity3D:Pick and select GameObjects
    推荐:将NSDT场景编辑器加入你的3D工具链3D工具集:NSDT简石数字孪生PickandselectGameObjects可以在Scene视图中或从Hierarchy窗口中选择一个游戏对象。也可以一次选择多个游戏对象。Unity会在Scene视图中突出显示选择的游戏对象及其子项。默认情况下,选择轮廓颜色为橙......