当前位置: 首页 > article >正文

浅谈C#之单线程流式适配器

一、基本介绍

        在C#中,单线程流式适配器通常用于处理流式数据,如网络通信或文件操作中的连续数据流。这些数据流可能是有序的,并且数据包之间可能会发生粘连,即没有明确的分界线,导致粘包和半包问题。解决这些问题的关键在于识别数据包的标识和顺序。

二、简单操作

流式单线程适配器的基本概念

流式单线程适配器在TouchSocket框架中被定义为处理有序流式数据的核心组件,它负责解析数据,包括解决数据的粘连和分包问题,以及将收到的数据解析为数据对象。

实现流式单线程适配器

在C#中,可以通过自定义适配器来实现流式单线程处理。以下是一个简单的示例,展示了如何使用Streambyte数组来读取和写入数据,同时处理粘包问题:

class Program
{
    static void Main(string[] args)
    {
        var directory = Directory.GetCurrentDirectory();
        var program = File.Open("Program.cs", FileMode.OpenOrCreate);
        var buffers = new byte[1024]; // 创建一个8k的缓存区
        var list = new List<byte>();
        while (true)
        {
            int length = program.Read(buffers, 0, buffers.Length);
            if (length <= 0)
            {
                break;
            }
            list.AddRange(buffers.Take(length));
        }
        program.Close();
        Console.WriteLine($"已读取:{list.Count}");
        var tempr = File.Open("Program_01.cs", FileMode.OpenOrCreate);
        tempr.Write(list.ToArray(), 0, list.Count);
        tempr.Close();
    }
}

使用流适配器

C#中的流适配器,如StreamReaderStreamWriter,提供了一种简化的方法来处理流数据。这些适配器封装了流操作,使得读写操作更加方便。例如,StreamReader可以按行读取文本,而StreamWriter可以写入文本并自动处理换行。

自定义流式单线程适配器

在更复杂的应用中,可能需要自定义流式单线程适配器来处理特定的协议或数据格式。这通常涉及到解析数据头和数据体,以及处理数据的顺序和完整性。以下是一个自定义适配器的示例,它展示了如何读取和解析数据:

var pos = byteBlock.Position; // 记录初始游标位置,防止本次无法解析时,回退游标。
var myRequestInfo = new MyRequestInfo();
// 此操作实际上有两个作用,
// 1.填充header
// 2.将byteBlock.Pos递增3的长度。
var header = byteBlock.ReadToSpan(3); // 填充header
var bodyLength = (byte)(header[0] - 2);
if (bodyLength > byteBlock.CanReadLength)
{
    // body数据不足。
    byteBlock.Position = pos; // 回退游标
    return FilterResult.Cache;
}
else
{
    // 此操作实际上有两个作用,
    // 1.填充body
    // 2.将byteBlock.Pos递增bodyLength的长度。
    var body = byteBlock.ReadToSpan(bodyLength);
    myRequestInfo.DataType = header[1];
    myRequestInfo.OrderType = header[2];
    myRequestInfo.Body = body.ToArray();
    request = myRequestInfo; // 赋值ref
    return FilterResult.Success; // 返回成功
}


http://www.kler.cn/a/394702.html

相关文章:

  • WSL2上Ubuntu22.04安装Docker
  • J9学习打卡笔记
  • 如何通过 360 驱动大师检查自己电脑上的显卡信息
  • STM32-笔记11-手写带操作系统的延时函数
  • 秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行
  • 基于推理的目标检测 DetGPT
  • 前端(1)——快速入门HTML
  • UI自动化测试|元素操作浏览器操作实践
  • 【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)
  • 黑马产品经理
  • 青少年编程与数学 02-003 Go语言网络编程 21课题、Go语言WebSocket编程
  • C#入门 020 事件(类型成员)
  • 膜计算 MATLAB例程(仅例程,无背景)
  • Linux 中自旋锁与信号量的区别
  • 网络初阶——运输层:TCP 协议(Part2)
  • docker构建jdk11
  • 拆解测试显示Mac Mini (2024)固态硬盘并未锁定 互换硬盘后仍可使用
  • Spring Data Redis常见操作总结
  • 深度学习之pytorch常见的学习率绘制
  • 【模块一】kubernetes容器编排进阶实战之etcd的介绍与使用
  • 基于树莓派的日志抓取工具制作
  • ssh和nfs
  • Vue之插槽(slot)
  • 力扣 LeetCode 344. 反转字符串(Day4:字符串)
  • 力扣889:根据先序和后序遍历构造二叉树
  • Spring Boot与Quartz定时任务集成:深入指南