使用boost :: asio从套接字读取JSON [英] Reading JSON from a socket using boost::asio

查看:163
本文介绍了使用boost :: asio从套接字读取JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently trying to transfer some JSON data over the network from a client to a server using the socket API of boost-asio. My client essentially does this:

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 )我找到了读取器在 std :: string ,char *数组或 std :: istream 我可以从 boost :: asio :: streambuf 操作传递给函数。

On the server side I have the choice between various boost::asio::async_read* functions. I wanted to use JsonCpp to parse the received data. Studying the JsonCpp API (http://jsoncpp.sourceforge.net/class_json_1_1_reader.html) I found that the Reader operates on top of either a std::string, a char* array or a std::istream which I could operate from the boost::asio::streambuf passed to the functions.

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

The point is that as far as I know it is not necessarily the case that the entire content is transferred at once, so I would need some kind of confirmation that the buffer contains sufficient data to process the entire document using JsonCpp. How can I assure that the buffer contains enough data?

推荐答案

这是应用程序级协议的一个区域

This is an area for application level protocol


  • 读取直到流结束(发送方断开连接);这不适用于为多个消息保持活动的连接

  • 提供 Content-Length:12346 \r\\\
    提前知道要读多少

  • 提供分隔符(有点像mime边界,但您可以使用任何不允许/支持的序列作为一部分JSON有效负载)( async_read_until

  • 将有效负载视为二进制风格顺序)长度字段。

  • read until the stream end (the sender disconnects); this doesn't work with connections that are kept alive for more than a single message
  • supply a header like Content-Length: 12346\r\n to know in advance how much to read
  • supply a delimiter (a bit like mime boundaries, but you could use any sequence that is not allowed/supported as part of the JSON payload) (async_read_until)
  • Treat the payload as "binary-style" (BSON e.g.) and supply a (network-order) length field before the text transmission.

ASIO Http服务器示例包含一个漂亮的模式,用于解析您可以使用的HTTP请求/标头。这假设您的解析器可以检测完整性,只有软失败,直到所有信息存在。

The ASIO Http server example contains a pretty nice pattern for parsing HTTP request/headers that you could use. This assumes that your parser can detect completeness and just 'soft-fails' until all information is present.

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解析JSON Spirit earlier 使用QJsonDocument 将子字符串解析为JSON;你可以使用它来检测正确的JSON文档的结束(如果它不完整,结束将与开始一致)

I've provided an answer that parses JSON using Boost Spirit earlier Parse a substring as JSON using QJsonDocument; you could use this to detect the end of a proper JSON document (and if it's incomplete, the end will coincide with the start)

这篇关于使用boost :: asio从套接字读取JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆