我使用boost :: asio的基本示例来连接到一个enpoint并获得一个json响应。这是代码
boost::asio::streambuf response;
boost::asio::read_until(socket_, response, "\r\n");
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
LOG_ERROR << "invalid response";
return -1;
}
resp_status_code_ = status_code;
resp_status_code_ = status_code;
if (status_code != 200) {
LOG_ERROR << "response did not returned 200 but " << status_code;
return -1;
}
//read until the response headers termination
boost::asio::read_until(socket_, response, "\r\n\r\n");
//read the headers.
std::string header;
while (std::getline(response_stream, header) && header != "\r") {
;
}
std::ostringstream ostringstream_content;
if (response.size() > 0)
ostringstream_content << &response;
boost::system::error_code error;
boost::system::error_code error;
while (true) {
size_t n = boost::asio::read(socket_, response, boost::asio::transfer_at_least(1), error);
if (!error)
{
if (n)
ostringstream_content << &response;
}
if (error == boost::asio::error::eof)
break;
if (error)
return -1; //throw boost::system::system_error(error);
}
str_response_ = ostringstream_content.str();
但是当字符串返回时我正在读这个
1 [5a0
2 {"a_token":"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0Nzk5Mjk2NjcsIn...030"}
3 0
4
5 ]
[和]是我的代码中的标记,用于相应地调试数据的开始和结束。我在第一行有多行,3个有问题的字符,即5a0,第二行中的json字符串是正确的然后 一个零和一个空行。我怎样才能完全获得json字符串?
答案 0 :(得分:1)
我重写了你的例子,它对我来说很好。请注意,我没有用于阅读响应的快捷方式。我正在一次性阅读状态行和标题而不是单独阅读(纯粹是出于懒惰)
#include <asio.hpp>
#include <iostream>
#include <sstream>
#include <istream>
int main(int argc, const char * argv[]) {
static asio::io_service ios;
asio::ip::tcp::endpoint
endpoint(asio::ip::address::from_string("127.0.0.1"), 8000);
asio::generic::stream_protocol::socket socket{ios};
socket.connect(endpoint);
std::string req = "GET /api\n\r\n\r\n";
std::error_code ec;
socket.write_some(asio::buffer(req, req.size()), ec);
std::cout << "Request sent" << std::endl;
if (ec == asio::error::eof) {
std::cerr << "Premature termination\n";
return 1;
}
//while (true) {
{
asio::streambuf response;
// Get till all the headers
asio::read_until(socket, response, "\r\n\r\n");
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
std::cout << "V : " << http_version << std::endl;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
std::cerr << "invalid response";
return -1;
}
if (status_code != 200) {
std::cerr << "response did not returned 200 but " << status_code;
return -1;
}
//read the headers.
std::string header;
while (std::getline(response_stream, header) && header != "\r") {
std::cout << "H: " << header << std::endl;
}
std::ostringstream ostringstream_content;
if (response.size() > 0) {
ostringstream_content << &response;
}
std::error_code error;
while (true) {
size_t n = asio::read(socket, response, asio::transfer_at_least(1), error);
if (!error) {
if (n) {
ostringstream_content << &response;
}
}
if (error == asio::error::eof) {
break;
}
if (error) {
return -1; //throw boost::system::system_error(error);
}
}
auto str_response = ostringstream_content.str();
std::cout << str_response << std::endl;
}
//}
return 0;
}
我的python服务器用于测试:
Python 2.7.10 (default, Jul 14 2015, 19:46:27)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket as s
>>> sd = s.socket(s.AF_INET, s.SOCK_STREAM)
>>> sd.bind(("127.0.0.1", 8000))
>>> sd.listen(1)
>>> c, a = sd.accept()
>>> resp = "HTTP/1.1 200 OK\nDate: Fri, 31 Dec 1999 23:59:59 GMT\nContent-Type: text/plain\nTransfer-Encoding: chunked\n\r\n\r\n{\"token\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0Nzk5Mjk2NjcsIn...030\"}"
>>> c.send(resp)
173
>>> exit()
ASIO输出:
MacBook-Pro:asio_test amuralid$ ./json_read_so
Request sent
V : HTTP/1.1
H: Date: Fri, 31 Dec 1999 23:59:59 GMT
H: Content-Type: text/plain
H: Transfer-Encoding: chunked
{"token":"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0Nzk5Mjk2NjcsIn...030"}