c#优雅高效的读取字节数组——不安全代码(1)
在开发上位机的经历中,会有很多需要和下位机交互通信的场景,大多数都会定义一个和硬件的通信协议,最终在上位机代码中的形式其实就是符合通信协议的字节数组。
场景
在控制一些车辆进行货物搬运的业务场景下,我们需要即时的获取小车的状态数据,并且做出解析,最后进行业务处理。不管与下位机是如何通信的,最终都会读取到一个字节数组在内存中。
以TCP通讯为例子,一般会在通讯协议的报文头中定义报文的长度,从而解决一些通讯问题,如粘包等,最后读取到正文部分。
如何解析字节数组到类或结构体中
建立与通信协议一致的结构体
比如通讯协议的正文格式定义如下:
| id | motor_steps | speed |
|---|---|---|
| 1字节 | 2字节 | 1字节 |
- id 小车编号
- motor_steps 小车行走累计马达步数
- speed 小车当前速度
在代码中建立对应的结构体
[StructLayout(LayoutKind.Explicit)]
public struct VehicleStatus
{
[FieldOffset(0)] public byte id;
[FieldOffset(1)] public ushort motor_steps;
[FieldOffset(3)] public byte speed;
}
使用不安全代码将字节数组映射到结构体中
byte[] metaData = new byte[4] { 10, 88, 89, 5 }; //模拟一段报文
unsafe
{
fixed (byte* metaPointer = metaData)
{
VehicleStatus* status = (VehicleStatus*)metaPointer;
Console.WriteLine($"小车编号:{status->id}");
Console.WriteLine($"小车速度:{status->speed}");
Console.WriteLine($"小车马达步数:{status->motor_steps}");
}
}
代码解释
StructLayout
表示某个类或者结构体里的成员的排列方式,这里我们使用LayoutKind.Explicit精确模式,该模式必须配合FieldOffset属性一起制定字段的物理内存排列位置。
fixed
用来钉住可移动变量,确保GC在执行期间对不会重新定位或释放包含对象实例,如果位置变了或者被释放了,谁还管你的非托管的指针对象呢?这边字节数组肯定是一个可移动变量了。
c#优雅高效的读取字节数组——不安全代码(1)的更多相关文章
- 使用 mina 传输大字节数组
转载自:http://seara520.blog.163.com/blog/static/16812769820103214817781/ 使用mina传输超过2k以上的数据时(采用tcp方式,如果是 ...
- JAVA IO分析二:字节数组流、基本数据&对象类型的数据流、打印流
上一节,我们分析了常见的节点流(FileInputStream/FileOutputStream FileReader/FileWrite)和常见的处理流(BufferedInputStream/B ...
- java 读取文件的字节数组
/*文件64位编码*/ public static void main(String[] args) { byte[] fileByte = toByteArray(newFile); St ...
- Java基础知识强化之IO流笔记27:FileInputStream读取数据一次一个字节数组byte[ ]
1. FileInputStream读取数据一次一个字节数组byte[ ] 使用FileInputStream一次读取一个字节数组: int read(byte[] b) 返回值:返回值其实是实际 ...
- byte字节的输入流 建议使用字节数组形式接受内容 因为当输入流是汉字时候 会超出字节的范围 出现无法读取的现象
byte字节的输入流 建议使用字节数组形式接受内容 因为当输入流是汉字时候 会超出字节的范围 出现无法读取的现象
- IO流处理文件读取到字节数组,再从字节数组读取到文件,Java实现
package cn.zhang.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; impo ...
- Java将文件转为字节数组
Java将文件转为字节数组 关键字:文件,文件流,字节流,字节数组,二进制 摘要:最近工作中碰到的需求是,利用http传输二进制数据到服务器对应接口,需要传输userId, file(加密后)等一系列 ...
- 【.net】从比较两个字节数组谈起
上午,有位初学者朋友问:如何比较两个字节数组中各字节是否相等? 不许笑,我一向反对嘲笑初学者,初学者不认真学习时你可以批评,但不能讥嘲.你不妨想想,你自己开始学习编程的时候又是什么个光景? 好,于是, ...
- Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)
一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...
- mina 字节数组编解码器的写法 II
I 里面的写法不够严谨,这也是我之前说它简陋的主要原因,下面来个更加严谨.完整一点儿的: ByteArrayEncoder.java package org.bruce.mina.cpp.codec; ...
随机推荐
- badapple最后一步,讲黑白图转为字符图,然后输出就行了。
from PIL import Image import os char_s = list(" .,-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\ ...
- C_C++常用函数汇总
1 string.h.cstring(C) (1)字符串连接函数 strcat.strncat strcat(char[ ], const char[ ]) strncat(char[ ], cons ...
- 【接口测试】Postman(二)-Postman Echo
Postman Echo Postman Echo为用户提供API调用的示例服务.简而言之,就是官方提供的一个API帮助文档.初学者可以通过它很快的掌握Postman工具.我们下面将一一介绍他们. ...
- Web请求与响应(SpringBoot)
Web请求与响应 Web的工作原理可以分为以下几个步骤: 输入URL:Web客户端使用Web浏览器输入所需访问的URL(统一资源定位符). 建立连接:Web浏览器与Web服务器之间建立TCP/IP连接 ...
- 月光宝盒(vivo流量录制回放平台)正式对外开源
作者:vivo 互联网服务器团队- Liu Yanjiang 月光宝盒是一个基于流量录制回放的自动化测试平台,通过录制回放取代编写脚本进行自动化回归,提升测试效率和覆盖率.因为其解决方案具有很强的通用 ...
- python实现关闭usb功能
禁用usb和启用usb 一禁用usb自动加载功能 公司内部有时候需要禁用usb接口的文件拷贝,但是打印机,扫描枪等待其他设备的使用,我们应该怎么做呢,很简单,可以通过修改BIOS,注册表和第三方软件实 ...
- [SrpingBoot]初步搭建springboot应用,报错:Failed to configure a DataSource: 'url' attribute is not specified and no embedd[转载]
1 错误信息 Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource ...
- 和 chatgpt 聊了一会儿分布式锁 redis/zookeeper distributed lock
前言 最近的 chatGPT 很火爆,听说取代程序员指日可待. 于是和 TA 聊了一会儿分布式锁,我的感受是,超过大部分程序员的水平. Q1: 谈一谈 java 通过 redis 实现分布式 锁 ch ...
- JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述
可以后端开发的 javascript引擎有 Chrome V8 基于C++ java的Rhino引擎(JDK6被植入),Java8 被替换为Nashorn Rhino和Nashorn都是用Java实现 ...
- 600 条最强 Linux 命令总结
600 条最强 Linux 命令总结 每博一文案 你有千万条微博想写,可有些根本不重要,后来你才懂那是你怕别人看穿你所以才把真话埋在日常里.你有千万句话想说,可点开那 个对话框,你根本打不出一个字.你 ...