[英]boost::asio::buffer with vectors structs
我有2个问题:
在我的信息结构中,如果我使用float
或double
类型而不是std::string
则可以正常工作,但是如果我按如下方式使用std::string
,则在我的客户端部分中会收到该结构,但之后它就会崩溃。
我t even send it using
std :: vector` t even send it using
,就像这样:
struct info
{
int id;
std::string name;
};
int main(int argc, char** argv)
{
boost::asio::io_service ios;
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
boost::asio::ip::tcp::socket cl1(ios);
cl1.open(ep.protocol());
boost::system::error_code ec;
cl1.connect(ep, ec);
if (ec == 0)
cout << "Connected" << endl;
else {
cout << "Not connected" << endl;
system("pause");
return -2;
}
info student;
student.id = 7;
student.name = "Rasul";
cl1.send(boost::asio::buffer(&student, sizeof(student)));
if (ec == 0)
cout << "Written" << endl;
else {
cout << "Not written" << endl;
system("pause");
return -2;
}
cout << "Done" << endl;
system("pause");
return 0;
}
- 在我的信息结构中,如果我使用
float
或double
类型而不是std::string
则可以正常工作,但是如果我按如下方式使用std::string
,则在我的客户端部分中会收到该结构,但之后它就会崩溃。
这是因为float
或double
是POD数据类型,而std::string
不是,违反了合同:
boost::asio::buffer
函数用于创建表示原始内存,POD元素数组,POD元素向量或std::string
的缓冲区对象。
确切地说,它们的意思是“ [[POD元素的(数组|向量)]]或[a std::string
]” ,当您查看重载列表时,这很清楚
添加一个静态断言,您将看到:
static_assert(std::is_pod<info>::value, "whoops, that can't work");
cl1.send(boost::asio::buffer(&student, sizeof(student)));
如果要序列化,则必须编写一些代码。 假设总体上体系结构独立性和可移植性不是问题¹,则可以:
int32_t id_and_size[] = {student.id, static_cast<int32_t>(student.name.length())};
assert(id_and_size[1] >= 0); // because `size_t` is unsigned and larger than int32_t
cl1.send(boost::asio::buffer(id_and_size));
cl1.send(boost::asio::buffer(student.name.data(), student.name.length()));
这会将长度与数据分开发送: Live On Coliru]( http://coliru.stacked-crooked.com/a/897573028a86e16e )
00000000:0700 0000 0500 0000 5261 7375 6c ........ Rasul
虽然这是容易出错和乏味的。 如果您控制两端,请考虑使用序列化框架(Boost序列化,Google Protobuf ...)
¹因为您已经提到序列化double
等的原始二进制格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.