c++传输二进制数据
文章目录
- 一、前提
- 二、二进制和指针相关概念
- 1、二进制数据传输的本质
- 2、指针相关概念
- (1)float* 和char*类型的指针有什么区别吗
- (2)c语言关于指针和长度的理解
- 3、二进制传输步骤
- 三、vector构造string对象
- 1、vector和string的内存是否连续
- (1)vector容器
- (2)string对象
- 2、vector<float>和string的转换
- (1)std::vector<float> 转string
- (2)string转float
- 3、其他注意的点
- (1) to_string的精度问题
- (2)把一个vector追加到另一个vector的后面
- 四、总结
一、前提
需求是使用c++
的httplib
库传输二进制的数据。传输前获取到的数据类型是std::vector<float>
类型。
那么传输的数据要如何转换成二进制呢?二进制传输本质上传的是什么?为什么要进行指针的类型转换和长度转换?疑问有很多,不得不总结下了。
二、二进制和指针相关概念
1、二进制数据传输的本质
首先明确,数据在计算机内存中的存储方式是二进制的,在进行数据传输的时候,从内存中读取出来的数据就是二进制的数据。
因此,如果能保证数据存储上的连续性的话,我们只需要告诉httplib
,传输数据的指针地址是什么,传输数据的长度是多少即可。httplib
进行数据通信的时候,直接根据指针地址+len
的方式就可以把数据都读出来进行发送。
2、指针相关概念
首先: c++
是对c
的一层封装,c
里面关于内存数据的操作需要两个条件,一个是指针,一个是长度。
针对连续的内存,可以通过指针+长度的方式来操作内存。
(1)float* 和char*类型的指针有什么区别吗
本质上都是指向数据的存储地址,区别在于指针类型,以及读出数据时候的格式转换。
float*类型的指针:指针运算的时候,因为float是4个字节,需要转成1个字节,因此需要size*4.
char*类型的指针:指针运算的时候,因为char是1个字节,因此直接获取size即可
(2)c语言关于指针和长度的理解
1)指针类型的理解
参考:02深入理解C指针之—指针类型和值
指针指向的类型,只有知道指针指向的类型,才能明白指针在内存中的具体分布情况。特别是在指针的算术运算时,指针指向的类型决定要分配的内容的分布。
2)指针的值
指针的值是指指针指向的某块内存区域的首地址,指针的内存区域可以用使用sizeof
关键字获取指针的内存区域的大小,是以字节为单位,如果想获取指针上指针类型的大小,须要使用sizeof(指针名称)/sizeof(指针类型)
3)野指针和释放指针
野指针的出现:int *ptrnum; 只是声明指针,而不进行初始化出现野指针,野指针是内存泄漏的一种常见情况
参考:C++ 跟野指针说bye bye!
3、二进制传输步骤
(1)获取vector容器的首元素地址指针,转换成char*格式,方便构造string对象。
(2)获取vector容器的size,因为float是4个字节,需要转成1个字节,因此需要size*4
(3)构造string对象是为了方便数据传输,socket操作的也是char类型的数据,且char类型占用字节比较少,因此这里转换成string类型,方便传输中的操作。通过vector的首个元素地址指针去迭代,从内存中读取数据,然后拷贝到string对象的连续内存块中(4) 实际网络传输的时候,会读取string对象,获取到char*指针,然后根据len长度来读取内存中的数据,这部分数据在内存中是以二进制的方式存储的,因此传输的是这部分二进制数据,也叫二进制传输。
注意:指针类型的改变只是为了保证数据的读取格式,以及明确根据len读取数据的地址步长,本质上数据是没有改变的,依然在内存中存储。
三、vector构造string对象
1、vector和string的内存是否连续
(1)vector容器
其底层所采用的数据结构非常简单,就只是一段连续的线性内存空间。 vector
容器可以看做是一个动态数组,array
容器则是静态数组。
data
() : 返回指向容器中第一个元素的指针。
(2)string对象
STL
的字符串类在申请内存的时候,总是切一块完整的内存。你可以理解为char* pString = new char[需要的尺寸]。
string
类围绕这快内存进行了管理,如果新加入字符串,它会在原有的基础上使用realloc
来扩大连续内存段。删除同理,所以String
类的内存总是连续的。
c++的httplib库在构造参数的时候,参数类型是std::string,因此,需要转换类型,从vector转换成string类型。
2、vector和string的转换
(1)std::vector 转string
std::vector<float> test_f;
//1、转换成char*
//2、利用string的构造函数构造
std::string ctc_log_prob_str((const char*)test_f.data(), test_f.size()*sizeof(float));
(2)string转float
auto *p_data = (float*) string.c_str(); //转换成float*
vector<float> data_float(p_data, p_data + file_len / sizeof(float)); //根据地址和len构造vector
把生成的string
对象作为参数传给server
端即可,server
端通过req.get_file_value("xx").content.c_str()
获取char*
指针,然后处理数据。
3、其他注意的点
(1) to_string的精度问题
to_string
的精度默认是6
,如果想要保存更高精度的话,需要手动设置。
关于to_string的精度问题:stackoverflow关于to_string的精度问题
以及setprecision
设置精度,注意,这里设置的精度是全部字符的长度,
如果要针对小数点后的精度的话,需要加上:
setiosflags(ios::fixed)
std::cout << setiosflags(ios::fixed) << setprecision(3) << f;
参考:c++中setiosflags(ios::fixed)的用法
(2)把一个vector追加到另一个vector的后面
c++
中的vector
的插入操作有几个方法:
vector.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
vector.insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。vector.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值
vec1.insert(vec1.end(),vec2.begin(),vec2.end()); 将vec2插入到vec1尾部
四、总结
不得不承认,自己对比底层部分还是不够熟悉,特别是C语言的指针操作和对指针的理解上。有好有坏吧,知其然也要知其所以然,只要在前进的路上就好。共勉!
end
c++传输二进制数据相关推荐
- android上传二进制流到服务器,android – 通过ADB shell传输二进制数据(即使...
参见英文答案 > Read binary stdout data from adb shell?????????????????????????????????????16个 我一直在尝试使用类 ...
- java字符串 直接能网络传输吗_atitit.二进制数据无损转字符串网络传输
atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 gbk会造成信息丢失 由于有些字符在gbk字符集中找不到对应的字符,所以默认使用编码63 ...
- WebSocket系列之二进制数据设计与传输
概述 通过前三篇博客,我们能够了解在通过WebSocket发送数据之前,我们需要传递的数据是如何变成ArrayBuffer二进制数据的:在我们收到二进制数据之后,我们又如何将其变成了JavaScrip ...
- C#蓝牙连接及传输数据的三种方式(蓝牙传输文件、二进制数据)
先下载InTheHand.Net.Personal.dll并在C#中引用,这个需要在网上下载 第一种.通过ObexWebRequest传输文件 先看界面 using InTheHand.Net; us ...
- java xml二进制流传输_XML中二进制数据的处理方法
XML中二进制数据的处理方法 在xml中,所有的数据都是以文本的形式来显示,但是二进制数据不能直接以文本格式来表示,那xml又是怎么处理二进制数据的呢?下面就来探讨一下. 为了简单和通用性,xml被设 ...
- h5如何上传文件二进制流_前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输...
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...
- 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器
28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...
- 微型计算机可以处理的二进制数据长度,可以处理二进制数据长度的是
大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 字长是计算机信息处理中能同时处理的二进制数据的长度.二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数. ...
- Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)
前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下SignalR吧,如下: ASP.NET S ...
最新文章
- python装饰器改变命运
- CSDN×易观算法大赛火热进行中~
- 钢结构计算机模拟拼装,钢结构技术-钢结构虚拟预拼装技术
- excel自动填充下方相同数据
- VB操作excel 格式设置及打印页面设置(精简)
- 在win7的iis下部署asp网站
- parallel scavenge 与parnew 区别:
- php 微信二维码设置中间logo
- 努比亚 系统升服务器设置,努比亚Nubia x6官方系统升级教程与方法
- 帝国cms搜索php分页,帝国cms灵动标签分页的实现方法
- 留存分析_游戏数据分析
- 判断二极管导通例题_通信电源 | 1个二极管是如何改变电流的?
- 正交化(Orthogonalization)
- 上“天”入“地”,都少不了亚马逊云科技这个云引擎
- php网站建设实训引言_PHP的开发环境搭建与网站设计实现分析论文
- c语言stricmp函数,stricmp ( )【C语言库函数源代码】
- 一周歪评丨马化腾天天看你的微信?库克薪酬千万却排最末?硅谷高管不为人知的一面
- 2023年3月-4月各大学网络教育统考大学英语B题库与考试时间
- nvidia linux 黑屏,Ubuntu卡logo、卡住、黑屏无法正常启动、屏幕和键盘背光无法调节等一系列问题的罪恢祸首:NVIDIA显卡驱动...
- QT软件开发-基于FFMPEG设计视频播放器-解码音频(三)