如何在boost.asio中打印请求?



我使用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数据包来重置连接。

  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';
}   
}

最新更新