C# Socket发送、接收结构体数组

C# Socket发送、接收结构体-CSDN博客

 

C# Socket发送、接收结构体数组按以下步骤操作:

一、Socket发送结构体数组

定义结构体数组

首先,根据给定的结构体定义,创建一个结构体数组实例。

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct ST_BonefractureInfo
{public int nID;public float fScore;public int nLTX;public int nLTY;public int nRBX;public int nRBY;
}// 创建结构体数组实例,这里numElements是你需要发送的结构体元素数量。
ST_BonefractureInfo[] boneFractureInfos = new ST_BonefractureInfo[numElements];

填充结构体数组

根据实际业务逻辑,为结构体数组中的每个元素赋值。

for (int i = 0; i < numElements; i++)
{boneFractureInfos[i].nID = ...; // 填充IDboneFractureInfos[i].fScore = ...; // 填充分数boneFractureInfos[i].nLTX = ...; // 填充左上角X坐标boneFractureInfos[i].nLTY = ...; // 填充左上角Y坐标boneFractureInfos[i].nRBX = ...; // 填充右下角X坐标boneFractureInfos[i].nRBY = ...; // 填充右下角Y坐标
}

结构体数组到字节数组的转换

使用System.Runtime.InteropServices.Marshal类提供的方法将结构体数组转换为字节数组,以便通过Socket发送。

int structSize = Marshal.SizeOf(typeof(ST_BonefractureInfo));
int totalSize = structSize * numElements;byte[] buffer = new byte[totalSize];IntPtr ptr = IntPtr.Zero;
try
{ptr = Marshal.AllocHGlobal(totalSize);for (int i = 0; i < numElements; i++){Marshal.StructureToPtr(boneFractureInfos[i], ptr + (i * structSize), false);}Marshal.Copy(ptr, buffer, 0, totalSize);
}
finally
{if (ptr != IntPtr.Zero){Marshal.FreeHGlobal(ptr);}
}

这里,我们首先计算单个结构体的大小(structSize),然后计算整个结构体数组所需的总字节数(totalSize)。接着,分配一段足够大的未托管内存(IntPtr),逐个将结构体复制到这段内存中,并最终将内存中的数据复制到一个新的字节数组(buffer)中。

通过Socket发送字节数组

使用已经打开并连接好的Socket对象,调用其Send方法发送字节数组。

Socket socket = ...; // 获取已连接的Socket对象// 发送数据
socket.Send(buffer, 0, buffer.Length, SocketFlags.None);

确保Socket处于正确状态且连接已经建立。这里假设socket变量已经包含了正确的Socket实例。使用Send方法将之前准备好的字节数组发送出去。 

以上就是一个完整的C# Socket发送结构体数组的示例过程。在实际应用中,别忘了处理可能发生的异常以及确保Socket的正确关闭。

 

二、Socket接收结构体数组

接收字节数组

使用已连接的Socket对象,调用其Receive方法接收数据,并存储到一个字节数组中。

Socket socket = ...; // 获取已连接的Socket对象int receivedBytes = 0;
int totalBytesExpected = numElements * Marshal.SizeOf(typeof(ST_BonefractureInfo));
byte[] receivedBuffer = new byte[totalBytesExpected];while (receivedBytes < totalBytesExpected)
{int bytesReceived = socket.Receive(receivedBuffer, receivedBytes, totalBytesExpected - receivedBytes, SocketFlags.None);if (bytesReceived == 0) throw new Exception("Connection closed by remote host.");receivedBytes += bytesReceived;
}

这里假设你知道待接收的结构体数组大小(即numElements)。在循环中,持续调用Receive方法直到接收到所有预期的数据。如果在接收过程中发现连接被远程主机关闭,抛出异常。

从字节数组还原结构体数组

使用System.Runtime.InteropServices.Marshal类提供的方法将接收到的字节数组转换回结构体数组。

ST_BonefractureInfo[] receivedBoneFractureInfos = new ST_BonefractureInfo[numElements];IntPtr ptr = IntPtr.Zero;
try
{ptr = Marshal.AllocHGlobal(totalBytesExpected);Marshal.Copy(receivedBuffer, 0, ptr, totalBytesExpected);for (int i = 0; i < numElements; i++){receivedBoneFractureInfos[i] = (ST_BonefractureInfo)Marshal.PtrToStructure(ptr + (i * Marshal.SizeOf(typeof(ST_BonefractureInfo))), typeof(ST_BonefractureInfo));}
}
finally
{if (ptr != IntPtr.Zero){Marshal.FreeHGlobal(ptr);}
}

同样地,分配一段与接收到的字节数组大小相等的未托管内存,将字节数组复制到这段内存中。然后,遍历内存区域,每次从指定偏移量处将内存数据转换为对应的结构体对象,并添加到结构体数组中。 

现在,receivedBoneFractureInfos变量就包含了从Socket接收并解析得到的结构体数组。你可以进一步处理或使用这些数据了。记得处理可能出现的异常,并确保Socket的正确关闭。

 

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

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

相关文章

【基础】在GCC中编译和链接不是一个命令

在 GCC&#xff08;GNU Compiler Collection&#xff09;中&#xff0c;编译和链接不是一个命令。编译是将源代码转换为目标代码的过程。它主要进行语法检查、词法分析、生成中间代码等操作。链接是将多个目标文件和库文件组合成一个可执行文件的过程。在 GCC 中&#xff0c;通…

实战1-批量爬取百度图片(上)

任务需求&#xff1a;输入关键字下载100个图片保存到本地&#xff0c;每个关键字单独存放一个文件夹&#xff08;GUI版&#xff09; 任务描述&#xff1a;当输入关键字时会爬取100个与关键词有关的图片到本地每个关键词单独保存到一个文件夹中&#xff0c;比如说我输入黑客下载…

SpringBoot(二)【整合第三方技术】

1、SpringBoot 整合第三方框架 1.1、整合 JUnit 我们先回顾一下在学习 SpringMVC 的时候&#xff0c;我们当时整合 Spring 和 JUnit 是这么整合的&#xff1a; 注意&#xff1a;如果测试类在 SpringBoot 启动类的包或者子包中&#xff0c;可以省略启动类的设置&#xff0c;也…

【面试经典 150 | 二叉树层序遍历】二叉树的层平均值

文章目录 写在前面Tag题目来源题目解读方法一&#xff1a;层序遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

4.18日paddleocr报错记录

No Images in train dataset, please ensure 1. The images num in the train label_file_list should be larger than or equal with batch size. 2. The annotation file and path in the configuration file are provided normally. 发现是ch_PP-OCRv3_rec.yml的loader的问…

设计模式——策略模式20

策略模式是一种行为设计模式&#xff0c; 它能让你定义多种算法或行为方式&#xff0c; 并将具体实现放入独立的类中&#xff0c; 以使算法的对象能够相互替换。使用场景例如活动中多种打折策略。 策略抽象 /*** author ggbond* date 2024年04月18日 08:02*/ public interfa…

Hive进阶(1)----HDFS写入数据流程(赋图助君理解)

HDFS写入数据流程 1.理论流程描述 HDFS&#xff08;Hadoop分布式文件系统&#xff09;的数据写入流程是一个复杂但高效的过程&#xff0c;可以分为以下8个步骤&#xff1a; 1、client(客户端)发起文件上传请求&#xff1b; 2、通过发送RPC请求与NameNode建立通讯。NameNode…

【MySQL篇】mysqlpump和mysqldump参数区别总汇(第三篇,总共四篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…

递归 python

↵一、简单理解 解决问题的一种方法&#xff0c;它将问题不断的分成更小的子问题&#xff0c;直到子问题可以用普通的方法解决。通常情况下&#xff0c;递归会使用一个不停调用自己的函数。 【注】&#xff1a;每一次递归调用都是在解决一个更小的问题&#xff0c;如此进行下…

python安装pytorch@FreeBSD(失败)

pip 安装 在FreeBSD系统下pip安装pytorch&#xff0c;报错 Building wheels for collected packages: pytorchBuilding wheel for pytorch (setup.py) ... errorerror: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully.│ exit code: 1╰…

内核编译-02

1配置【u-boot】 查看版本信息 对arm文件进行编译的专用工具 打开脚本文件 配置脚本文件 编译【.c】文件 创建目录&#xff0c;解压文件夹&#xff1a; 编译【smdk2440_config】&#xff0c;并产生【u-boot.bin】&#xff1a; 2配置开发板对应的配置文件 这里采用菜单…

基于深度学习的光场超分辨率算法综述

摘要&#xff1a;光场图像分辨率低的原因之一是光场空间分辨率和角度分辨率之间存在相互制约。光场超分辨率技术旨在从低分辨率光场图像中重建出高分辨率光场图像。基于深度学习的光场超分辨率方法通过学习高、低分辨率光场图像之间的映射关系来提升图像的质量&#xff0c;突破…

亚马逊Bedrock凭借Anthropic的开创性Claude 3系列扩展了AI产品组合

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

云服务器部署Springboot项目

前端项目打包 修改ip地址 在控制台输入npm run build:prod 会产生dist文件 将dist文件中的内容移动至/usr/local/nginx/html目录下 后端项目打包 修改ip地址 执行clean操作 执行install操作 将生成的target文件中的jar包移动至/usr/local/src目录下 启动 注意⚠️&#xff…

动态规划-不同路径

LCR 098. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 对于动态规划类型的题目&#xff0c;可以从以下角度去思考问题 1. 状态表示 机器人在每一个网格节点的状态 dp[i][j] &#xff0c;可以理解从 起始点 为走到 [i,j] &#xff0c;一共有多少种方式&#xff1b; 2. …

vscode按ctrl+鼠标左键没反应

vscode按ctrl鼠标左键没反应 问题问题解决 问题 新买的阿里云服务器,在连接vscode后,按ctrl鼠标左键没反应,怎么办? 问题解决 你没有在vscode上安装c的相关插件,安装之后才可以实现按ctrl鼠标左键跳转到函数的定义

硬件设备杂记——12G SDI及 AES67/EBU

常见的 SDI线缆规格&#xff0c;HD-SDI又被称为1.5G-SDI&#xff0c;具体参数以秋叶原的参数为例 AES67/EBU 目前音频网络标准主要集中在OSI网络体系的第二层和第三层。 第二层音频标准的弊端在于构建音频网络时需要专用的交换机&#xff0c;无法利用现有的以太网络&#xff0c…

使用Django Rest Framework设计与实现用户注册API

使用Django Rest Framework设计与实现用户注册API 在现代Web应用开发中&#xff0c;RESTful API已成为前后端分离架构中的关键组件。Django Rest Framework (DRF) 是一款基于Django的优秀库&#xff0c;提供了丰富的工具和接口&#xff0c;极大地简化了RESTful API的设计与实现…

Oracle和SQL Server区别

首先&#xff0c;从操作的平台来看&#xff0c;Oracle具有更高的灵活性&#xff0c;它可以在所有主流平台上运行&#xff0c;并采用了开放的策略目标&#xff0c;使得客户可以选择最适合他们特定需要的解决方案。这意味着客户可以利用很多种第三方应用程序和工具。相比之下&…

Matlab|【免费】【sci】考虑不同充电需求的电动汽车有序充电调度方法

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现sci文献《A coordinated charging scheduling method for electric vehicles considering different charging demands》&#xff0c;主要实现电动汽车协调充电调度方法&#xff0c;该方法主要有以…