文章目录

  • 一、前提
  • 二、二进制和指针相关概念
    • 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++传输二进制数据相关推荐

  1. android上传二进制流到服务器,android – 通过ADB shell传输二进制数据(即使...

    参见英文答案 > Read binary stdout data from adb shell?????????????????????????????????????16个 我一直在尝试使用类 ...

  2. java字符串 直接能网络传输吗_atitit.二进制数据无损转字符串网络传输

    atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 gbk会造成信息丢失 由于有些字符在gbk字符集中找不到对应的字符,所以默认使用编码63 ...

  3. WebSocket系列之二进制数据设计与传输

    概述 通过前三篇博客,我们能够了解在通过WebSocket发送数据之前,我们需要传递的数据是如何变成ArrayBuffer二进制数据的:在我们收到二进制数据之后,我们又如何将其变成了JavaScrip ...

  4. C#蓝牙连接及传输数据的三种方式(蓝牙传输文件、二进制数据)

    先下载InTheHand.Net.Personal.dll并在C#中引用,这个需要在网上下载 第一种.通过ObexWebRequest传输文件 先看界面 using InTheHand.Net; us ...

  5. java xml二进制流传输_XML中二进制数据的处理方法

    XML中二进制数据的处理方法 在xml中,所有的数据都是以文本的形式来显示,但是二进制数据不能直接以文本格式来表示,那xml又是怎么处理二进制数据的呢?下面就来探讨一下. 为了简单和通用性,xml被设 ...

  6. h5如何上传文件二进制流_前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输...

    HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...

  7. 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器

    28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...

  8. 微型计算机可以处理的二进制数据长度,可以处理二进制数据长度的是

    大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 字长是计算机信息处理中能同时处理的二进制数据的长度.二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数. ...

  9. Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

    前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下SignalR吧,如下: ASP.NET S ...

最新文章

  1. python装饰器改变命运
  2. CSDN×易观算法大赛火热进行中~
  3. 钢结构计算机模拟拼装,钢结构技术-钢结构虚拟预拼装技术
  4. excel自动填充下方相同数据
  5. VB操作excel 格式设置及打印页面设置(精简)
  6. 在win7的iis下部署asp网站
  7. parallel scavenge 与parnew 区别:
  8. php 微信二维码设置中间logo
  9. 努比亚 系统升服务器设置,努比亚Nubia x6官方系统升级教程与方法
  10. 帝国cms搜索php分页,帝国cms灵动标签分页的实现方法
  11. 留存分析_游戏数据分析
  12. 判断二极管导通例题_通信电源 | 1个二极管是如何改变电流的?
  13. 正交化(Orthogonalization)
  14. 上“天”入“地”,都少不了亚马逊云科技这个云引擎
  15. php网站建设实训引言_PHP的开发环境搭建与网站设计实现分析论文
  16. c语言stricmp函数,stricmp ( )【C语言库函数源代码】
  17. 一周歪评丨马化腾天天看你的微信?库克薪酬千万却排最末?硅谷高管不为人知的一面
  18. 2023年3月-4月各大学网络教育统考大学英语B题库与考试时间
  19. nvidia linux 黑屏,Ubuntu卡logo、卡住、黑屏无法正常启动、屏幕和键盘背光无法调节等一系列问题的罪恢祸首:NVIDIA显卡驱动...
  20. QT软件开发-基于FFMPEG设计视频播放器-解码音频(三)

热门文章

  1. LeetCode40 Combination Sum II 解析
  2. [leetcode]Unique Paths II
  3. 客户端与服务器端通信方式总结
  4. 使用中文维基百科语料库训练一个word2vec模型 12.1
  5. 拥有着全球最大的拍客网络的短视频领头羊:梨视频的云上实践
  6. 微信24小时到账_微信转账24小时可撤销吗?延时到账功能可帮忙!
  7. TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
  8. android zooming bitmap
  9. 相机的变焦,对焦和景深的理解和照相機的成像原理
  10. 使用正则表达式检测帐号规范