我想通过网络传输数据,但我不想使用任何外部库(标准C/C++没问题).
例如:
unsigned int x = 123;
char y[3] = {'h', 'i', '\0'};
float z = 1.23f;
Run Code Online (Sandbox Code Playgroud)
我想要这个
char xyz[11];
Run Code Online (Sandbox Code Playgroud)
阵列.
注意:要通过网络传输它,我需要unsigned int(htonl函数)的网络字节顺序,然后我需要以某种方式将float序列化为IEEE 754格式(互联网上的许多功能),我知道.
如何让它们进入xyz-Array,端到端排列好,所以我可以用它作为socket + send()函数的缓冲区?显然我有反向功能(ntohl和反向IEEE 754)来解决它们,但我也需要一种技术,最好是相同的......
它会是这样的:
xyz in binary: 00000000 0000000 00000000 01111011 | 01101000 | 01101001 | 00000000 | 00111111 10011101 01110000 10100100 - big endian repr. of u. int 123 - | - 'h' - | - 'i' - | - '\0' - | - IEEE 754 repr of float 1.23 -
如何在没有外部库和最少使用标准库函数的情况下实现此目的?这不是我的计划,而是我的学习.
Car*_*kuk 18
啊,你想序列化原始数据类型!原则上,有两种方法:第一种方法是,您只需获取要序列化的数据的内部二进制表示形式,将其重新解释为一个字符,并在表示时使用它:
所以,如果你有一个:
双d;
你获取它的地址,重新解释该指针作为指向字符的指针,然后使用这些字符:
double *pd=&d;
char *pc = reinterpret_cast<char*>(pd);
for(size_t i=0; i<sizeof(double); i++)
{
char ch = *pc;
DoSomethingWith(ch);
pc++;
}
Run Code Online (Sandbox Code Playgroud)
这适用于所有原始数据类型.这里的主要问题是,binray表示是依赖于实现的(主要取决于CPU).(当你尝试使用IEEE NANs时,你会遇到微妙的错误...).
总而言之,这种方法根本不可移植,因为您无法控制数据的表示.
第二种方法是,使用更高级别的表示,您自己可以控制.如果性能不是问题,可以使用std :: strstream和>>和<<运算符将原始C类型变量流式传输到std :: strings.这很慢但易于阅读和调试,并且非常便于携带.
类似下面的代码会做到这一点.注意sizeof(unsigned int)在不同系统上的不同问题,这些问题会得到你.对于这样的事情,你最好使用定义明确的类型,比如int32_t.无论如何...
unsigned int x = 123;
char y[3] = {'h', 'i', '\0'};
float z = 1.23f;
// The buffer we will be writing bytes into
unsigned char outBuf[sizeof(x)+sizeof(y)+sizeof(z)];
// A pointer we will advance whenever we write data
unsigned char * p = outBuf;
// Serialize "x" into outBuf
unsigned int32_t neX = htonl(x);
memcpy(p, &neX, sizeof(neX));
p += sizeof(neX);
// Serialize "y" into outBuf
memcpy(p, y, sizeof(y));
p += sizeof(y);
// Serialize "z" into outBuf
int32_t neZ = htonl(*(reinterpret_cast<int32_t *>(&z)));
memcpy(p, &neZ, sizeof(neZ));
p += sizeof(neZ);
int resultCode = send(mySocket, outBuf, p-outBuf, 0);
[...]
Run Code Online (Sandbox Code Playgroud)
...当然接收代码会做类似的事情,除了反过来.