C#中处理Socket粘包

在C#中使用Socket进行网络通信时,粘包问题是常见的。粘包问题通常发生在TCP协议中,因为TCP是流式协议,数据可能会被分割成多个包发送,也可能多个小包会被合并成一个大包接收。

处理粘包问题的常见方法是使用消息分隔符或消息长度前缀。以下是使用消息长度前缀来处理粘包问题的示例代码。

发送端代码

在发送端,每条消息的前面加上一个固定长度的消息长度前缀。

using System;
using System.Net.Sockets;
using System.Text;public class Client
{public static void SendMessage(Socket socket, string message){byte[] messageBytes = Encoding.UTF8.GetBytes(message);byte[] lengthPrefix = BitConverter.GetBytes(messageBytes.Length);byte[] packet = new byte[lengthPrefix.Length + messageBytes.Length];Buffer.BlockCopy(lengthPrefix, 0, packet, 0, lengthPrefix.Length);Buffer.BlockCopy(messageBytes, 0, packet, lengthPrefix.Length, messageBytes.Length);socket.Send(packet);}
}

接收端代码

在接收端,首先读取消息长度前缀,然后根据长度前缀读取完整的消息。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;public class Server
{private const int LengthPrefixSize = 4;public static void StartListening(){IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);Socket listener = new Socket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp);try{listener.Bind(localEndPoint);listener.Listen(10);while (true){Socket handler = listener.Accept();ProcessClient(handler);}}catch (Exception e){Console.WriteLine(e.ToString());}}private static void ProcessClient(Socket handler){byte[] buffer = new byte[1024];int bytesRead = 0;while (true){// Read the length prefixbytesRead = handler.Receive(buffer, 0, LengthPrefixSize, SocketFlags.None);if (bytesRead == 0)break;int messageLength = BitConverter.ToInt32(buffer, 0);// Read the messageint totalBytesRead = 0;byte[] messageBuffer = new byte[messageLength];while (totalBytesRead < messageLength){bytesRead = handler.Receive(messageBuffer, totalBytesRead, messageLength - totalBytesRead, SocketFlags.None);if (bytesRead == 0)break;totalBytesRead += bytesRead;}string message = Encoding.UTF8.GetString(messageBuffer);Console.WriteLine("Received: {0}", message);}handler.Shutdown(SocketShutdown.Both);handler.Close();}
}

解释

  • 发送端:
  • 将消息转换为字节数组。
  • 计算消息的长度,并将长度作为前缀添加到消息前面。
  • 发送带有长度前缀的消息。
  • 接收端:
  • 首先读取固定长度的消息长度前缀。
  • 根据长度前缀读取完整的消息。
  • 将消息转换为字符串并处理。

通过这种方式,可以有效地解决TCP通信中的粘包问题。

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

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

相关文章

【Qt+opencv】ROI与图像混合

文章目录 前言ROIROI是什么如何提取ROI 图像混合整体混合线性混合 局部混合 总结 前言 在计算机视觉和图像处理中&#xff0c;我们经常需要对图像的某一部分&#xff08;也就是ROI&#xff0c;Region of Interest&#xff09;进行操作。这些操作可能包括滤波、缩放、旋转等。同…

SpringBoot 跨域请求处理全攻略:从原理到实践

文章目录 SpringBoot 如何处理跨域请求&#xff1f;你能说出几种方法&#xff1f;跨域请求概述跨域解决方案1. 使用CrossOrigin注解2. 使用WebMvcConfigurer配置类3. 使用过滤器&#xff08;Filter&#xff09;4. 使用Spring Security处理CORS5.使用Spring Cloud Gateway处理CO…

灵雀云AML:赋能金融AI,构建数智时代核心竞争力

在人工智能&#xff08;AI&#xff09;技术的迅猛发展中&#xff0c;金融行业正迈入变革的新时代。AI不仅在优化投资决策、信用评估、实时监控和欺诈识别方面展现出强大功能&#xff0c;还极大地提升了客户体验、降低了运营成本&#xff0c;并推动了产品创新。面对智能时代的挑…

C#知识|账号管理系统:多条件动态查询条件的编写。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 在项目开发中涉及到许多通过多个条件勾选来实现动态的多个条件查询的情况&#xff0c; 此节记录多条件查询的后台代码编写&#xff0c;以下为学习笔记。 01 实现原理 通过界面输入框输入或者下拉框下拉选择任意查询…

《RuoYi基于SpringBoot+Vue前后端分离的Java快速开发框架学习》系列博客_Part2_添加菜单

系列文章目录 Part1:启动RouYi 文章目录 系列文章目录Part1:启动RouYi 实现添加菜单功能来显示新的音图分析页面&#xff08;所截图片都是在已经添加菜单完成后的情况下&#xff09;一、建立一个菜单二、建立数据库1、通过数据库软件建立一个表&#xff0c;供我们使用&#xf…

强化学习算法DQN实现

DQN的基本思想 Q学习&#xff1a;Q学习是一种基于值函数的强化学习方法&#xff0c;目的是通过学习状态-动作值函数Q(s, a)来指导智能体的动作选择。Q函数表示在状态s采取动作a后能够获得的期望总回报。 深度神经网络&#xff1a;使用深度神经网络来近似Q函数。输入是状态s&am…

【Ngix】快速上手,由浅入深

内容概述 1、nginx 简介 &#xff08;1&#xff09;介绍 nginx 的应用场景和具体可以做什么事情 &#xff08;2&#xff09;介绍什么是反向代理 &#xff08;3&#xff09;介绍什么是负载均衡 &#xff08;4&#xff09;介绍什么是动静分离 2、nginx 安装 &#xff08;1…

Leetcode - 周赛406

目录 一&#xff0c;3216. 交换后字典序最小的字符串 二&#xff0c;3217. 从链表中移除在数组中存在的节点 三&#xff0c;3218. 切蛋糕的最小总开销 I 四&#xff0c;3219. 切蛋糕的最小总开销 II 一&#xff0c;3216. 交换后字典序最小的字符串 本题要求交换一次相邻字符…

C++编程逻辑讲解step by step:静态数组长度后确定还能编译成功

定义 定义一维数组的一般格式为 类型标识符 数组名&#xff3b;常量表达式&#xff3d;&#xff1b; 例如&#xff1a; int a&#xff3b;10&#xff3d;; 问题 很多人写成这样&#xff1a; int n; cin>>n; int a[n]; 这个写法已经明确&#xff0c;是错的&…

新建vue项目和安装第三方库

安装vue 打开vscode编辑器&#xff0c;按Ctrl组合键打开终端&#xff0c;在命令行中运行以下命令 npm create vuelatest项目初始化完成&#xff0c;可执行以下命令&#xff1a; cd vue-project --切换到项目目录 npm install -- 安装依赖包 npm run dev -- 运行项目安装 …

大数据架构对比记录

Lambda架构 -维护两套项目&#xff0c;开发和维护成本高 -两套链路&#xff0c;数据容易不一致 -数据计算成本大&#xff08;例如原定每小时计算一次&#xff0c;但有额外新需求需要计算两点半-三点半之间数据&#xff0c;则需要重新计算&#xff09; Kappa -过于依赖kafka消…

FPGA:基于复旦微FMQL10S400 /FMQL20S400 国产化核心板

复旦微电子是国内集成电路设计行业的领军企业之一&#xff0c;早在2000年就在香港创业板上市&#xff0c;成为行业内首家上市公司。公司的RFID芯片、智能卡芯片、EEPROM、智能电表MCU等多种产品在市场上的占有率位居行业前列。 今天介绍的是搭载复旦微 FMQL10S400/FMQL20S400的…

嵌入式Linux应用开发基础-现有动态库so的使用

前言 最近做嵌入式Linux项目&#xff0c;需要调用客户提供的现成的动态库(so文件&#xff0c;包含对应头文件)&#xff0c;我这边用的是cmake来构建。 此篇文章主要是记录一下嵌入式Linux的动态库的使用&#xff0c;与君共勉&#xff01; 一、通过cmake使用so库和对应的头文件…

01数据结构 - 顺序表

这里是只讲干货不讲废话的炽念&#xff0c;这个系列的文章是为了我自己以后复习数据结构而写&#xff0c;所以可能会用一种我自己能够听懂的方式来描述&#xff0c;不会像书本上那么枯燥和无聊&#xff0c;且全系列的代码均是可运行的代码&#xff0c;关键地方会给出注释^_^ 全…

C++客户端Qt开发——常用控件(容器类控件)

6.容器类控件 ①GroupBox 带标题分组框 属性 说明 title 分组框的标题 alignment 分组框内部内容的对齐方式 flat 是否是"扁平"模式 checkable 是否可选择 设为true,则在title前方会多出一个可勾选的部分. check 描述分组框的选择状态&#xff08;前提…

数据结构(5.1)——树的性质

结点数总度数1 结点的度——结点有几个孩子(分支) 度为m的树、m叉树的区别 度为m的树第i层至多有 个结点(i>1) 高度为h的m叉树至多有 个结点 高度为h的m叉树至少有h个结点 、高度为h&#xff0c;度为m叉树至多有hm-1个结点 具有n个结点的m叉树的最小高度为 总结

通过角点进行水果的果梗检测一种新方法

一、前言 在前面的《数字图像处理与机器视觉》案例一&#xff08;库尔勒香梨果梗提取和测量&#xff09;中主要使用数学形态学的方法进行果梗提取&#xff0c;下面给出一种提取果梗的新思路。 众所周知&#xff0c;一般果梗和果实在边缘处角度有较大突变&#xff0c;可以通过合…

探索WebKit的CSS列表与标记:美化列表的艺术

探索WebKit的CSS列表与标记&#xff1a;美化列表的艺术 CSS列表和标记是网页设计中用于增强列表展示效果的重要工具。WebKit&#xff0c;作为多种现代浏览器的内核&#xff0c;包括Safari、QQ浏览器等&#xff0c;提供了对CSS列表和标记的广泛支持。本文将深入探讨WebKit对CSS…

spring security源码追踪理解(一)

一、前言 近期看了spring security相关的介绍&#xff0c;再加上项目所用若依框架的底层安全模块也是spring security&#xff0c;所以想从源码的角度加深下对该安全模块的理解&#xff08;看源码之前&#xff0c;我们要先有个意识&#xff0c;那就是spring security安全模块主…

Solus Linux简介

以下是学习笔记&#xff0c;具体详实的内容请参考官网&#xff1a;Home | Solus Solus Linux 是一个独立的 Linux 发行版&#xff0c;它以其现代的设计、优化的性能和友好的用户体验而著称。以下是一些关于 Solus Linux 的最新动向和特点&#xff1a; 1. **最新版本发布**&a…