【问题标题】:How can I print the requests in boost.asio?如何在 boost.asio 中打印请求?
【发布时间】:2021-01-25 09:57:20
【问题描述】:

我正在使用boost.asio 编写一个简单的服务器。下面的代码试图做两件事:

  1. 打印请求
  2. 回复客户hello

但事实并非如此。

#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main(){
    
        try{
    
                boost::asio::io_context ioc;
                tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), 1010));
                for(;;){
                        tcp::socket socket(ioc);
                        acceptor.accept(socket);
                        boost::system::error_code err;
                        std::string buff;
                        socket.read_some(boost::asio::buffer(buff), err);
                        std::cout << buff << '\n';
                        boost::asio::write(socket, boost::asio::buffer("hello"),err);
    
                }   
        }   
        catch (std::exception& e){ 
    
                std::cerr << e.what() << '\n';
        }   

        return 0;

}

当我运行服务器并使用curl 发送请求时,它没有响应,只打印一个空行。

[amirreza@localhost ~]$ curl 127.0.0.1:1010
curl: (1) Received HTTP/0.9 when not allowed

[amirreza@localhost ~]$ 

在服务器端(2个空行):

[amirreza@localhost 2]$ sudo ./server 
[sudo] password for amirreza: 


这里我有两个问题:

  • 为什么服务器不打印 curl 请求?
  • 为什么 curl 没有收到 hello 消息?

我还观察到在wireshark 中服务器和curl 之间发送和接收的数据包。一开始会发生 tcp 握手,但是当 curl 发送 HTTP 请求时,服务器会响应一个带有 RST 标志的 tcp 数据包以重置连接。

【问题讨论】:

  • 你永远不会检查write()的返回值。这样做。
  • @JohnZwinck 我刚刚检查了write()的返回值,是6,有帮助吗?

标签: c++ networking boost-asio


【解决方案1】:
  1. 我注意到的第一件事:

    std::string buff;
    socket.read_some(boost::asio::buffer(buff), err);
    

    这读入一个空字符串:0 字节。预留空间:

    buff.resize(1024);
    socket.read_some(boost::asio::buffer(buff), err);
    

    或使用具有组合读取操作的动态缓冲区(请参阅下一个)

  2. read_some 读取任何可用的内容,不一定是一行。有关更高级别的读取操作,请参阅 read_until

    std::string buff;
    read_until(socket, boost::asio::dynamic_buffer(buff), "\n");
    
  3. 处理错误。在您的情况下,您可以简单地删除 ec 变量,并依赖异常,因为您已经处理了这些

修复

#include <boost/asio/buffer.hpp>
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main(){
    try{
        boost::asio::io_context ioc;
        tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(),  11010));
        for(;;) {
            tcp::socket socket(ioc);
            acceptor.accept(socket);
            std::string buff;
            auto bytes = read_until(socket, boost::asio::dynamic_buffer(buff), "\n");
            std::cout << buff.substr(0, bytes) << std::flush;
            boost::asio::write(socket,  boost::asio::buffer("hello"));
        }   
    }   
    catch (std::exception const& e){ 
        std::cerr << e.what() << '\n';
    }   
}

【讨论】:

  • 感谢您的回答,您知道为什么我的 curl 仍然没有显示服务器响应吗?在这种情况下hello
  • Curl 需要一个 HTTP 服务器。可能工作的最简单的事情:coliru.stacked-crooked.com/a/397242355895f3d7 另外,请确保您不打印二进制数据(您发送“hello\0”)以便 curl 打印它(或使用--output - 无论如何尝试)
  • 要真正解析/编写有效的 HTTP 请求/响应,为什么不使用 Boost Beast? coliru.stacked-crooked.com/a/77523ba8f77df287
  • 我不确定,但是即使是消息hello 也没有显示在wireshark 中。
猜你喜欢
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 2018-06-07
  • 2016-08-17
  • 2021-08-14
  • 2013-09-27
  • 2014-09-04
相关资源
最近更新 更多