Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
113 views
in Technique[技术] by (71.8m points)

c++ - How can I print the requests in boost.asio?

I'm using boost.asio to write a simple server. The code below is trying to do 2 things:

  1. print the request
  2. respond to the client hello

but it does not.

#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 << '
';
                        boost::asio::write(socket, boost::asio::buffer("hello"),err);
    
                }   
        }   
        catch (std::exception& e){ 
    
                std::cerr << e.what() << '
';
        }   

        return 0;

}

When I run the server and send a request using curl it does not respond and only print an empty line.

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

[amirreza@localhost ~]$ 

and in server side (2 empty line):

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


here I have 2 questions:

  • why server doesn't print the curl request?
  • why curl doesn't receive the hello message?

I also observed packets sent and received between server and curl in wireshark. At first the tcp handshake will occur but when curl send the HTTP request, the server respond a tcp packet with RST flag to reset the connection.

question from:https://stackoverflow.com/questions/65882464/how-can-i-print-the-requests-in-boost-asio

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  1. First thing I notice:

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

    This reads into an empty string: 0 bytes. Either reserve space:

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

    or use a dynamic buffer with a composed read operation (see next)

  2. read_some reads whatever is available, not necessarily a line. see read_until for higher level read operations

    std::string buff;
    read_until(socket, boost::asio::dynamic_buffer(buff), "
    ");
    
  3. handle errors. In your case you could simply remove the ec variable, and rely on exceptions since you alreaady handle those

Fixes

#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), "
");
            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() << '
';
    }   
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...