gpt4 book ai didi

c++ - 使用 boost::asio 从套接字读取 JSON

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:28:52 24 4
gpt4 key购买 nike

我目前正在尝试使用 boost-asio 的套接字 API 通过网络将一些 JSON 数据从客户端传输到服务器。我的客户基本上是这样做的:

int from = 1, to = 2;

boost::asio::streambuf buf;
ostream str(&buf);

str << "{"
<< "\"purpose\" : \"request\"" << "," << endl
<< "\"from\" : " << from << "," << endl
<< "\"to\" : " << to << "," << endl
<< "}" << endl;

// Start an asynchronous operation to send the message.
boost::asio::async_write(socket_, buf,
boost::bind(&client::handle_write, this, _1));

在服务器端,我可以在各种 boost::asio::async_read* 函数之间进行选择。我想使用 JsonCpp 来解析接收到的数据。研究 JsonCpp API ( http://jsoncpp.sourceforge.net/class_json_1_1_reader.html) 我发现 Reader 在 std::string、char* 数组或 std::istream 之上运行我可以从传递给函数的 boost::asio::streambuf 进行操作。

要点是,据我所知,不一定会一次传输全部内容,因此我需要某种确认缓冲区包含足够的数据来使用 JsonCpp 处理整个文档。如何确保缓冲区包含足够的数据?

最佳答案

这是应用层协议(protocol)的领域

要么

  • 读取直到流结束(发送者断开连接);这不适用于为多个消息保持事件状态的连接
  • 提供一个像 Content-Length: 12346\r\n 这样的标题来提前知道要阅读多少内容
  • 提供一个分隔符(有点像 mime 边界,但您可以使用任何不允许/不支持的序列作为 JSON 负载的一部分)(async_read_until)
  • 将有效负载视为“二进制样式”(例如 BSON)并在文本传输之前提供一个(网络顺序)长度字段。

ASIO Http 服务器示例包含一个非常好的模式,用于解析您可以使用的 HTTP 请求/ header 。这假设您的解析器可以检测完整性并且只是“软故障”,直到所有信息都存在。

void connection::handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
if (!e)
{
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
request_, buffer_.data(), buffer_.data() + bytes_transferred);

if (result)
{
request_handler_.handle_request(request_, reply_);
boost::asio::async_write(socket_, reply_.to_buffers(),
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
else if (!result)
{
reply_ = reply::stock_reply(reply::bad_request);
boost::asio::async_write(socket_, reply_.to_buffers(),
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
else
{
socket_.async_read_some(boost::asio::buffer(buffer_),
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
else if (e != boost::asio::error::operation_aborted)
{
connection_manager_.stop(shared_from_this());
}
}

我之前提供了一个使用 Boost Spirit 解析 JSON 的答案 Parse a substring as JSON using QJsonDocument ;您可以使用它来检测正确的 JSON 文档的结尾(如果不完整,结尾将与开头一致)

关于c++ - 使用 boost::asio 从套接字读取 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24428293/

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