从boost asio向浏览器发送多个响应

时间:2017-06-22 06:51:05

标签: c++ boost https

我正在开发一个接收请求的HTTPS服务器,必须回复3个回复。前两个是行ACK,最后一个包含请求的信息。

我正在使用我的网络浏览器(chrome)作为客户端。我想要的是以下内容:

  • 浏览器(客户端)向服务器发送请求。
  • 服务器发送第一个ACK(一个html页面),浏览器显示它。
  • 两秒钟后,服务器发送另一个ACK(不同的html页面),浏览器显示它。
  • 再过两秒钟,服务器发送请求的信息(不同的html页面),浏览器显示它。

问题是浏览器只收到第一个ACK,它似乎在读取后关闭套接字,甚至在Connection标头中将keep-alive设置为HTTPS

有没有办法等待网络浏览器的多个HTTPS响应?

来源

这包含在请求时由服务器执行的异步方法:

void handle_handshake(const boost::system::error_code& error)
{
    if (!error)
    {
      boost::asio::async_read_until(socket_, request_, "\r\n\r\n",
          boost::bind(&session::handle_read, this,
            boost::asio::placeholders::error));
    }
    else
    {
      std::cout << "ERROR, deleting. " << __FILE__ << ":" << __LINE__ << std::endl;
      delete this;
    }
}

void handle_read(const boost::system::error_code& err)
{
    if (!err)
    {   
      std::string s = "some_response";

      // First write. This write is received by the browser without problems.
      boost::asio::async_write(socket_,
          boost::asio::buffer(response),
          boost::bind(&session::handle_write, this,
          boost::asio::placeholders::error));
    }   
    else
    {   
      std::cout << "Error: " << err << "\n";
    }   
}

void handle_write(const boost::system::error_code& error)
{
    if (!error)
    {
      if(n++ <= 2)
      {
        // Second and third writes.
        // These ones are not read by the browser.
        if(n == 1)
        {
          std::string s = "some_response2";

          boost::asio::async_write(socket_,
              boost::asio::buffer(response),
              boost::bind(&session::handle_write, this,
              boost::asio::placeholders::error));
        }
        else if (n==2)
        {
            std::string s = "some_response3";

            boost::asio::async_write(socket_,
              boost::asio::buffer(response),
              boost::bind(&session::handle_write, this,
              boost::asio::placeholders::error));
        }
        sleep(1);
      }
    }
    else
    {
      std::cout << "ERROR, deleting: " << __FILE__ << ":" << __LINE__ << std::endl;
      delete this;
    }
}

1 个答案:

答案 0 :(得分:1)

好的,你想要克服缓慢的启动,即采用新连接并为新连接进行3次握手 - 完整的往返延迟。

虽然我无法获得正确的代码片段。一个疯狂的猜测是你必须忘记为保持连接或使用错误的HTTP版本设置超时(SO_RCVTIMEOSO_SNDTIMEO)。

注意:默认情况下,在HTTP / 1.1中启用保持活动连接,而不在HTTP / 1.0中启用。 HTTP / 1.0旨在在客户端和服务器之间的每个请求之后关闭连接。我们实际上可以使用telnet检查这种差异。

从性能角度来看,我编写了两个(python)脚本 - 一个用于连续50个请求的相同连接,一个为每个请求启动一个新连接。

Average time with keep-alive/persistent connections: 7.00 seconds
Average time with new connections: 22.38 seconds

这是差不多3个订单的差异,因为我们知道保持活动/持久连接,避免了三次握手(延迟的完整往返)。慢启动不会对此产生太大影响,因为请求和响应非常小,因此所需的带宽量非常低。

PS:如果有帮助,请浏览this

boost::asio::ip::tcp::socket socket(io_service);
...
boost::asio::socket_base::keep_alive option;
socket.get_option(option);

客户端需要在配置(预先假定)服务器以监听特定端口的特定应用程序时保持端口打开

我从here

获得了上述代码段