如何使用boost :: asio访问Web服务

How to access web service using Boost::Asio?

本文关键字:Web 服务 访问 asio boost 何使用      更新时间:2023-10-16

我想知道是否有可能使用boost asio库访问Web服务。

我尝试了以下代码(在iOS,C 11中(,这些代码从Boost Asio文档中获得。但这会引发以下内容。

try
{
    boost::asio::io_service io_service;
    std::string address = "http://www.thomas-bayer.com/axis2/services/BLZService/";
    // Get a list of endpoints corresponding to the server name.
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(address,boost::asio::ip::resolver_query_base::numeric_service);

    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    endpoint_iterator->host_name() = "www.thomas-bayer.com/axis2/services/BLZService/";
    std::cout<<"Print Query --"<<std::endl;
    // Try each endpoint until we successfully establish a connection.
    tcp::socket socket(io_service);
    boost::asio::connect(socket, endpoint_iterator);
    // Form the request. We specify the "Connection: close" header so that the
    // server will close the socket after transmitting the response. This will
    // allow us to treat all data up until the EOF as the content.
    boost::asio::streambuf request;
    std::ostream request_stream(&request);
    request_stream << "POST: HTTP/1.0rn";
    request_stream << "Host: " << address << "rn";
    request_stream << "Accept: */*rn";
    request_stream << "Connection: closernrn";
    // Send the request.
    boost::asio::write(socket, request);
    // Read the response status line. The response streambuf will automatically
    // grow to accommodate the entire line. The growth may be limited by passing
    // a maximum size to the streambuf constructor.
    boost::asio::streambuf response;
    boost::asio::read_until(socket, response, "rn");
    // 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/")
    {
        std::cout << "Invalid responsen";
        return;
    }
    if (status_code != 200)
    {
        std::cout << "Response returned with status code " << status_code << "n";
        return;
    }
    // Read the response headers, which are terminated by a blank line.
    boost::asio::read_until(socket, response, "rnrn");
    // Process the response headers.
    std::string header;
    while (std::getline(response_stream, header) && header != "r")
        std::cout << header << "n";
    std::cout << "n";
    // Write whatever content we already have to output.
    if (response.size() > 0)
        std::cout << &response;
    // Read until EOF, writing data to output as we go.
    boost::system::error_code error;
    while (boost::asio::read(socket, response,
                             boost::asio::transfer_at_least(1), error))
        std::cout << &response;
    if (error != boost::asio::error::eof)
        throw boost::system::system_error(error);
}
catch (std::exception& e)
{
    std::cout << "Exception: " << e.what() << "n";
}

异常:连接:无法分配请求的地址

例外:解决:找不到主机(权威(

代码有什么问题?还是我做错了?

谢谢

名称分辨率失败,因为您正在混淆请求,URL,协议,主机名和IP地址。

在FQDN上执行请求。除非您知道,否则您需要提供服务。在这种情况下,该服务遵循协议¹,`http://通常在端口80上提供:

std::string const address = "www.thomas-bayer.com";
tcp::resolver::query query(address, "80", boost::asio::ip::resolver_query_base::numeric_service);

请注意,在大多数系统上,您可以等效地使用:

std::string const address = "www.thomas-bayer.com";
tcp::resolver::query query(address, "http");

查看http://www.thomas-bayer.com零件的去向?

现在/axis2/services/BLZService/是查询路径,就像您在Get请求中写的那样:

request_stream << "GET /axis2/services/BLZService/ HTTP/1.1rn";

注意:

  1. 帖子不是标题(所以没有结肠!(,它是http"动词"(获取,帖子,删除,put ...(
  2. (
  3. "主机"标头主机名:

     request_stream << "Host: " << address << "rn";
    

    是正确的 iff address确实是主机的逻辑名称

  4. 设置主机名:

     endpoint_iterator->host_name() = "www.thomas-bayer.com/axis2/services/BLZService/";
    

    是我从未见过的东西,我不确定它应该取得什么成就。也许这是错误的?

¹通过惯例,可能是其他

修复

#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;
void test() try {
    boost::asio::io_service io_service;
    std::string const address = "www.thomas-bayer.com";
    // Get a list of endpoints corresponding to the server name.
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(address, "80", boost::asio::ip::resolver_query_base::numeric_service);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    std::cout << "Print Query --" << std::endl;
    // Try each endpoint until we successfully establish a connection.
    tcp::socket socket(io_service);
    boost::asio::connect(socket, endpoint_iterator);
    // Form the request. We specify the "Connection: close" header so that the
    // server will close the socket after transmitting the response. This will
    // allow us to treat all data up until the EOF as the content.
    boost::asio::streambuf request;
    std::ostream request_stream(&request);
    request_stream << "GET /axis2/services/BLZService HTTP/1.0rn";
    request_stream << "Host: " << address << "rn";
    request_stream << "Accept: */*rn";
    request_stream << "Connection: closernrn";
    // Send the request.
    boost::asio::write(socket, request);
    // Read the response status line. The response streambuf will automatically
    // grow to accommodate the entire line. The growth may be limited by
    // passing a maximum size to the streambuf constructor.
    boost::asio::streambuf response;
    boost::asio::read_until(socket, response, "rn");
    // Check that response is OK.
    std::istream response_stream(&response);
    std::string http_version, status_message;
    unsigned int status_code;
    std::getline(response_stream >> http_version >> status_code, status_message);
    if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
        std::cout << "Invalid responsen";
        return;
    }
    if (status_code != 200) {
        std::cout << "Response returned with status code " << status_code << "n";
        return;
    }
    // Read the response headers, which are terminated by a blank line.
    boost::asio::read_until(socket, response, "rnrn");
    // Process the response headers.
    std::string header;
    while (std::getline(response_stream, header) && header != "r")
        std::cout << header << "n";
    std::cout << "n";
    // Write whatever content we already have to output.
    if (response.size() > 0)
        std::cout << &response;
    // Read until EOF, writing data to output as we go.
    boost::system::error_code error;
    while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
        std::cout << &response;
    if (error != boost::asio::error::eof)
        throw boost::system::system_error(error);
} catch (std::exception &e) {
    std::cout << "Exception: " << e.what() << "n";
}
int main() { test(); }