gpt4 book ai didi

c++ - 在接收器端Boost Asio读取序列化的结构

转载 作者:行者123 更新时间:2023-12-02 10:15:17 26 4
gpt4 key购买 nike

我是新来的 push 和网络;)。我正在使用boost::asio制作客户端服务器应用程序,我需要将结构作为消息传递,因此使用了boost::asio::serialization:

test.h

#pragma once

#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
struct Test
{
public:
int a;
int b;
template<typename archive> void serialize(archive& ar, const unsigned version) {
ar & a;
ar & b;
}
};

客户端发送:
void send_asynchronously(tcp::socket& socket) {
Test info;

info.a = 1;
info.b = 2;

{
std::ostream os(&buf);
boost::archive::binary_oarchive out_archive(os);
out_archive << info;
}

async_write(socket, buf, on_send_completed);
}

在接收方,我将数据读入 boost::asio::buffer,我想知道一种解析此缓冲区并在服务器端提取对象的方法。请帮忙。

最佳答案

您没有显示足够的代码来知道如何声明buf或管理生存期。

我假设您使用了boost::asio::streambuf buf;,它具有静态的存储期限(命名空间范围)或是类成员(但您没有显示类)。

无论哪种方式,无论您拥有什么,都可以相反地“相同”接收。

这是一个简化的版本(省去了异步,因此我们不必猜测上面提到的事物的生命周期);

连接

让我们在本地主机上的端口3001处连接到一个假想的服务器(我们可以在下面做一个):

asio::io_context ioc;
asio::streambuf buf;
tcp::socket s(ioc, tcp::v4());
s.connect({{}, 3001});

连载

基本上,您拥有:
{
std::ostream os(&buf);
boost::archive::binary_oarchive oa(os);

Test req {13,31};
oa << req;
}

请注意流/归档周围的{}范围,请确保归档在发送之前完成。

发送
/*auto bytes_sent =*/ asio::write(s, buf);

接收

假设我们的服务器发送回另一个以相同方式序列化的 Test对象¹。

读入缓冲区,假设没有成帧,我们将“读到流的末尾”:
boost::system::error_code ec;
/*auto bytes_received =*/ asio::read(s, buf, ec);
if (ec && ec != asio::error::eof) {
std::cout << "Read error: " << ec.message() << "\n";
return 1;
}

In real life you want timeouts and limits to the amount of data read. Often your protocol will add framing where you know what amount of data to read or what boundary marker to expect.



反序列化
Test response; // uninitialized
{
std::istream is(&buf);
boost::archive::binary_iarchive ia(is);

ia >> response;
}

完整演示

Live On Coliru
#include <boost/asio.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <iostream>
namespace asio = boost::asio;
using tcp = boost::asio::ip::tcp;

struct Test {
int a,b;
template<typename Ar> void serialize(Ar& ar, unsigned) { ar & a & b; }
};

int main() {
asio::io_context ioc;
asio::streambuf buf;
tcp::socket s(ioc, tcp::v4());
s.connect({{}, 3001});

///////////////////
// send a "request"
///////////////////
{
std::ostream os(&buf);
boost::archive::binary_oarchive oa(os);

Test req {13,31};
oa << req;
}
/*auto bytes_sent =*/ asio::write(s, buf);

/////////////////////
// receive "response"
/////////////////////

boost::system::error_code ec;
/*auto bytes_received =*/ asio::read(s, buf, ec);
if (ec && ec != asio::error::eof) {
std::cout << "Read error: " << ec.message() << "\n";
return 1;
}

Test response; // uninitialized
{
std::istream is(&buf);
boost::archive::binary_iarchive ia(is);

ia >> response;
}

std::cout << "Response: {" << response.a << ", " << response.b << "}\n";
}

使用netcat模拟具有先前生成的响应 Test{42,99}(此处编码为base64)的服务器:
base64 -d <<<"FgAAAAAAAABzZXJpYWxpemF0aW9uOjphcmNoaXZlEgAECAQIAQAAAAAAAAAAKgAAAGMAAAA=" | nc -N -l -p 3001

它打印:
Response: {42, 99}  

¹由于Boost的二进制归档文件不可移植,因此它们在相同的体系结构上并使用相同版本的boost进行编译。 live demo很好地证明了这一点

关于c++ - 在接收器端Boost Asio读取序列化的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62193274/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com