c++传输二进制数据-创新互联
- 一、前提
- 二、二进制和指针相关概念
- 1、二进制数据传输的本质
- 2、指针相关概念
- (1)float* 和char*类型的指针有什么区别吗
- (2)c语言关于指针和长度的理解
- 3、二进制传输步骤
- 三、vector构造string对象
- 1、vector和string的内存是否连续
- (1)vector容器
- (2)string对象
- 2、vector
和string的转换 - (1)std::vector
转string - (2)string转float
- (1)std::vector
- 3、其他注意的点
- (1) to_string的精度问题
- (2)把一个vector追加到另一个vector的后面
- 四、总结
需求是使用c++
的httplib
库传输二进制的数据。传输前获取到的数据类型是std::vector
类型。
那么传输的数据要如何转换成二进制呢?二进制传输本质上传的是什么?为什么要进行指针的类型转换和长度转换?疑问有很多,不得不总结下了。
首先明确,数据在计算机内存中的存储方式是二进制的,在进行数据传输的时候,从内存中读取出来的数据就是二进制的数据。
因此,如果能保证数据存储上的连续性的话,我们只需要告诉httplib
,传输数据的指针地址是什么,传输数据的长度是多少即可。httplib
进行数据通信的时候,直接根据指针地址+len
的方式就可以把数据都读出来进行发送。
首先:c++
是对c
的一层封装,c
里面关于内存数据的操作需要两个条件,一个是指针,一个是长度。
针对连续的内存,可以通过指针+长度的方式来操作内存。
本质上都是指向数据的存储地址,区别在于指针类型,以及读出数据时候的格式转换。
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
() : 返回指向容器中第一个元素的指针。
STL
的字符串类在申请内存的时候,总是切一块完整的内存。你可以理解为char* pString = new char[需要的尺寸]。
string
类围绕这快内存进行了管理,如果新加入字符串,它会在原有的基础上使用realloc
来扩大连续内存段。删除同理,所以String
类的内存总是连续的。
c++的httplib库在构造参数的时候,参数类型是std::string,因此,需要转换类型,从vector转换成string类型。
2、vector和string的转换 (1)std::vector 转stringstd::vectortest_f;
//1、转换成char*
//2、利用string的构造函数构造
std::string ctc_log_prob_str((const char*)test_f.data(), test_f.size()*sizeof(float));
(2)string转floatauto *p_data = (float*) string.c_str(); //转换成float*
vectordata_float(p_data, p_data + file_len / sizeof(float)); //根据地址和len构造vector
把生成的string
对象作为参数传给server
端即可,server
端通过req.get_file_value("xx").content.c_str()
获取char*
指针,然后处理数据。
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
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享题目:c++传输二进制数据-创新互联
标题路径:http://hbruida.cn/article/dsssjs.html