C# 使用Pipelines处理Socket数据包

写在前面

在上一篇中对Pipelines进行简单的了解,同时也留下了未解的问题,如何将Pipelines类库运用到Socket通讯过程中来解决粘包和分包。链接地址如下: 初识System.IO.Pipelines icon-default.png?t=N7T8https://rjcql.blog.csdn.net/article/details/135211047

这一篇做了一个完整的demo,使用Pipelines接收和处理来自多个客户端发出的消息;相对于以往在报文包头放包体长度再结合结束符来判断的方式,确实要简洁了许多。

代码实现

服务端实现

using System.Net.Sockets;
using System.Net;
using System.Text;class Program
{static async Task Main(){SocketServerForPiplines();}static async void SocketServerForPiplines(){Console.WriteLine("Socket Server");// 创建服务端Socket对象var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);serverSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9090));serverSocket.ReceiveTimeout = 1000;serverSocket.SendTimeout = 1000;serverSocket.Listen(1000);Console.WriteLine("服务端启动监听");while (true){var clientSocket = serverSocket.Accept();Console.WriteLine("有客户端连上了");var handler = new PiplinesHandler(clientSocket);await handler.StartReceiveAsync();}Console.ReadLine();}
}

 PiplinesHandler 类:

using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace PipelinesTester
{public class PiplinesHandler{private const int _minimumBufferSize = 512;private Socket _socket;private Pipe _pipe;public PiplinesHandler(Socket socket){_socket = socket;var options = new PipeOptions(pauseWriterThreshold: 4096, resumeWriterThreshold: 1024);_pipe = new Pipe(options);}public async Task StartReceiveAsync(){Task receiveTask = ReceiveMessageAsync();Task processTask = ProcessMessageAsync();await Task.WhenAll(receiveTask, processTask);}private async Task ReceiveMessageAsync(){PipeWriter writer = _pipe.Writer;while (true){try{//从writer申请缓冲区Memory<byte> memory = writer.GetMemory(_minimumBufferSize);//从socket读取数据,直接写入到缓冲区中,即直接写入了PipeWriter中        int bytesRead = await _socket.ReceiveAsync(memory, SocketFlags.None);if (bytesRead == 0){break;}//前移写标志位writer.Advance(bytesRead);//通知Reader,可以读取了var result = await writer.FlushAsync();if (result.IsCompleted)break;}catch (Exception e){Console.WriteLine(e);break;}}await writer.CompleteAsync();try{_socket.Shutdown(SocketShutdown.Both);_socket.Close();}catch (Exception e){Console.WriteLine(e);}}private async Task ProcessMessageAsync(){PipeReader _pipeReader = _pipe.Reader;while (true){//读取消息var result = await _pipeReader.ReadAsync();var buffer = result.Buffer;//查找结束符            SequencePosition? position = buffer.PositionOf((byte)'\n');if (position == null){continue;}// 处理消息var line = buffer.Slice(0, position.Value);string msg = Encoding.UTF8.GetString(line);Console.WriteLine(msg);// 前移PipeReaderbuffer = buffer.Slice(buffer.GetPosition(1, position.Value));_pipeReader.AdvanceTo(buffer.Start, buffer.End);// Stop reading if there's no more data coming.if (result.IsCompleted){break;}}await _pipeReader.CompleteAsync();}}
}

客户端实现

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;class Program
{static void Main(string[] args){TcpClientTest();}static void TcpClientTest(){Console.WriteLine("TcpClient");var msg = $"这是来自客户端的消息{DateTime.Now.ToString("yyyy-MM-dd:HH:mm:ss")}\n";var client = new TcpClient("127.0.0.1", 9090);var sendStream = client.GetStream();var sendBytes = Encoding.Default.GetBytes(msg);sendStream.Write(sendBytes, 0, sendBytes.Length);sendStream.Flush();sendStream.Close();//关闭网络流  client.Close();//关闭客户端  Console.WriteLine(msg);Console.ReadLine();}
}

调用示例

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Web API系列】使用getDisplayMedia来实现录屏功能

文章目录 前言一、认识getD该处使用的url网络请求的数据。二、使用步骤1.使用方法一实现录屏2.使用方法二实现录屏3. 运行效果 延伸 前言 Web API经过长期的发展&#xff0c;尤其是最近&#xff0c;发展相当迅猛&#xff0c;现在已经支持很多功能了&#xff0c;一些原生就支持…

IRIS、Cache系统类汉化

文章目录 系统类汉化简介标签说明汉化系统包说明效果展示类分类%Library包下的类重点类非重点类弃用类数据类型类工具类 使用说明 系统类汉化 简介 帮助小伙伴更加容易理解后台系统程序方法使用&#xff0c;降低代码的难度。符合本土化中文环境的开发和维护&#xff0c;有助于…

月入7K, 95后护士转行网优,疫情之后,我选择辞掉“铁饭碗”

成为一个三甲医院的护士是什么体验&#xff1f; 如果你一毕业后就进入一家三甲医院&#xff0c;你可能会享受到稳定的就业环境、近在咫尺的机会与资源。 看似稳定与不错的薪资待遇&#xff0c;成为疫情之后普通打工人挤破脑袋也要进入的存在。似乎也能理解各地医院招聘时动辄80…

每日一题-----逆序字符串

大家好我是Beilef&#xff0c;在一个美好的下午我意外接触到编程并且产生了兴趣&#xff0c;哈哈我要努力成为一个跨界者&#xff0c;让我们一起加油吧O(∩_∩)O 文章目录 目录 文章目录 前言 大家好请上车 一、逆序字符串 题⽬描述&#xff1a; 输⼊⼀个字符串&#xff0c;写…

LabVIEW进行激光斑点图像处理与分析

LabVIEW进行激光斑点图像处理与分析 近年来&#xff0c;激光技术的应用日益繁荣。激光光斑的质量评估和分析技术决定了应用效果&#xff0c;对机器视觉、武器装备、光学测量和医疗设备产生深远影响。就具体用途和技术而言&#xff0c;激光光斑的采集和处理至关重要。即插即用的…

第十五节TypeScript 接口

1、简介 接口是一系列抽象方法的声明&#xff0c;是一些方法特征的集合&#xff0c;这些方法都应该是抽象的&#xff0c;需要有由具体的类去实现&#xff0c;然后第三方就可以通过这组抽象方法调用&#xff0c;让具体的类执行具体的方法。 2、接口的定义 interface interface_…

ElasticSearch 架构设计

介绍 ElasticSearchMySQLIndexTableDocumentRowFieldColumnMappingSchemaQuery DSLSQLaggregationsgroup by&#xff0c;avg&#xff0c;sumcardinality去重 distinctreindex数据迁移 ElasticSearch 中的一个索引由一个或多个分片组成 每个分片包含多个 segment&#xff08;分…

redis的搭建及应用(三)-Redis主从配置

Redis主从配置 为提升Redis的高可用性&#xff0c;需要搭建多个Redis集群以保证高可用性。常见搭建方式有&#xff1a;主从&#xff0c;哨兵集群等&#xff0c;本节我们搭建一主二从的多Redis架构。 redis主从安装1主2从的方式配置&#xff0c;以端口号为redis的主从文件夹。 主…

CSS 文字弹跳效果

鼠标移过去 会加快速度 <template><div class"bounce"><p class"text" :style"{animationDuration: animationDuration}">欢迎使用UniApp Vue3&#xff01;</p></div> </template><script> export d…

Java架构师系统架构设计实践

目录 1 导语2 架构设计实践本章概述3 架构设计要素概述和规划4 架构设计模式5 架构设计输入6 架构设计输出7 架构设计要素总结 想学习架构师构建流程请跳转&#xff1a;Java架构师系统架构设计 1 导语 Java架构师在进行系统架构设计时&#xff0c;需要综合考虑多个方面&#…

【三维生成】稀疏重建、Image-to-3D方法(汇总)

系列文章目录 总结一下近5年的三维生成算法&#xff0c;持续更新 文章目录 系列文章目录一、LRM&#xff1a;单图像的大模型重建&#xff08;2023&#xff09;摘要1.前言2.Method3.实验 二、SSDNeRF&#xff1a;单阶段Diffusion NeRF的三维生成和重建&#xff08;ICCV 2023&am…

【网络安全 | 网络协议】结合Wireshark讲解TCP三次握手

前言 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的传输层协议。在建立 TCP 连接时&#xff0c;需要进行三次握手&#xff0c;防止因为网络延迟、拥塞等原因导致的数据丢失或错误传输&#xff0c;确保双方都能够正常通信。 TCP三次握手在Wireshark数据包中…

线程学习(3)-volatile关键字,wait/notify的使用

​ &#x1f495;"命由我作&#xff0c;福自己求"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;线程学习(2)​​​​ 一.volatile关键字 volatile关键字是多线程编程中一个非常重要的概念&#xff0c;它主要有两个功能&#xff1a;保证内存可见性…

漏洞复现--用友NC Cloud XXE

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

【译文】IEEE白皮书 6G 太赫兹技术的基本原理 2023版

第一章 简介 太赫兹波是介于微波和光波之间的光谱区域&#xff0c;频率从 0.1THz ~ 10THz 之间&#xff0c;波长在 3mm ~ 30μm 之间。提供大块连续的频带范围以满足对 Tbit/s 内极高数据传输速率的需求&#xff0c;使该区域成为下一代无线通信&#xff08;6G&#xff09;的重…

Django(三)

1.快速上手 确保app已注册 【settings.py】 编写URL和视图函数对应关系 【urls.py】 编写视图函数 【views.py】 启动django项目 命令行启动python manage.py runserverPycharm启动 1.1 再写一个页面 2. templates模板 2.1 静态文件 2.1.1 static目录 2.1.2 引用静态…

《软件需求分析报告》

第1章 序言 第2章 引言 2.1 项目概述 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 …

html旋转相册

一、实验题目 做一个旋转的3d相册&#xff0c;当鼠标停留在相册时&#xff0c;相册向四面散开 二、实验代码 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" con…

Tg-5511cb: tcxo高稳定性+105℃高温

爱普生推的一款TG-5511CB是一种高稳定的TCXO温补晶体振荡器&#xff0c;频率范围十分广泛从 10mhz ~ 54mhz&#xff0c;它的电源电压只需要3.3V&#xff0c;无论是手机还是其他电子设备&#xff0c;都能轻松提供稳定的电力支持。频率/温度特性表现出色&#xff0c;0.28 10^6Ma…

uniapp中uview的text组件

基本使用&#xff1a; 通过text参数设置文本内容。推荐您使用:textvalue的形式 <u--text text"我用十年青春,赴你最后之约"></u--text>设置主题&#xff1a; 通过type参数设置文本主题&#xff0c;我们提供了五类属性。primary error success warning…