使用boost :: asio从套接字读取JSON [英] Reading JSON from a socket using boost::asio
问题描述
我目前正在尝试使用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屋!