我正在构建一个ostringstream。
我正在将int
写入此流。
我在2个数字之间使用stream<<" ";
。
我将此流转换为字符串,UDP将其发送。
在接收方,我使用这些函数将字符串拆分为“”空格字符的单个数字。
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
现在我想写二进制数据,所以
使用写入功能我正在写二进制数据,例如
来自此处的数据结构(http://robot.kaist.ac.kr/haptics/chai3d-2.0.0_Doc/resources/html/structc_matrix3d.html)
void insert_into_stream(std::ostream& stream, const cMatrix3d rot)
{
cVector3d column;
unsigned int byteCounter = 0;
int length = sizeof(double)*3;
char insert_buffer[sizeof(double)*9];
column = rot.getCol0();
memcpy(insert_buffer, &column[0], length);
stream.write(insert_buffer, length);
byteCounter += length;
column = rot.getCol1();
memcpy(insert_buffer+byteCounter, &column[0], length);
stream.write(insert_buffer, length);
byteCounter += length;
column = rot.getCol2();
memcpy(insert_buffer+byteCounter, &column[0], length);
stream.write(insert_buffer, length);
}
到流中并用空格字符分隔每个条目。
这不能很好地工作,好像我添加了15个这样的数据结构,然后在接收器端使用split方法,这取决于我有时会获得超过15个字符串的数据,例如18,因为二进制数据本身可能在其中包含ascii空格字符。至少这就是我认为的问题所在。
如何解决这个问题?
--- ----编辑 我在开始时添加了一些整数后,在流中添加了这15个数据结构,因此我需要使用split方法来获取这些初始数。
答案 0 :(得分:2)
如果发送二进制数据,则不会使用/需要'分隔符'。您将知道每种大小的写入和读取需要多少字节。例如。如果您的数字类型为uint32_t
,则这些数字将来自流中的四个字节。
但是我从您的编辑中看到,您需要一些机制来解除/序列化更复杂的数据结构。我建议使用一些更合适的协议,例如Google Protocol Buffers
答案 1 :(得分:0)
有几个问题。最直接的是你 输出固定长度的二进制数据,但尝试将其解析为 输入的可变长度(部分)文本数据。通常情况下, 二进制浮点将具有固定长度(但它取决于 在二进制格式,我知道例外)。二进制 积分数据通常也有固定长度,但是 可变长度并不罕见(例如Google的协议块)。
第二个也是更普遍的问题是你只是倾销
输出流的位,没有任何格式。意思就是
在将来的某个时候,你几乎肯定无法做到
重新阅读它们。如果您要将数据溢出,此技术就可以了
磁盘,因为它不适合内存,而数据只会
稍后通过相同的过程重读。否则,你需要
定义一种格式,并根据它输出(和输入)
定义。 (这是istream::read
和ostream::write
的原因
char*
取void*
,而非{{1}}。)