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

标签 c++ boost https

我正在开发一个 HTTPS 服务器,它接收一个请求并且必须用 3 个响应来回答。前两个是 something line ACKs,最后一个包含请求的信息。

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

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

问题是浏览器只收到第一个ACK,好像是读完就关闭socket,连Connection设置成keep-alive HTTPS header 。

有什么方法可以等待网络浏览器的多个 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;
    }
}

最佳答案

好吧,您想要克服启动缓慢的问题,即建立新连接并为新连接进行 3 次握手——一个完整的往返延迟。

虽然我无法获得有关您如何执行此操作的正确代码片段。一个大胆的猜测是您一定是忘记了为保持连接设置超时(SO_RCVTIMEOSO_SNDTIMEO)或者使用了错误的 HTTP 版本。

注意:在 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 得到了上面的片段

关于c++ - 从 boost asio 向浏览器发送多个响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44692139/

相关文章:

C++;编译时警告 "enabled by default"是什么意思?

c++ - 为什么 decltype 不能与重载函数一起使用?

c++ - 从 boost::variant 按索引获取项目,就像使用 std::variant 一样

c++ - Boost.PropertyTree 在遍历一些空树时崩溃

java - Java 6 支持 TLS1.2

c++ - Qt 同步原语可以与非 QThread 线程一起使用吗?

c++ - 为什么我的数组声明为引用数组

c++ - 在 Boost.Log 中过滤非平凡的记录器?

https - 这个 TLS 警报是什么意思?

.net - webHttpBinding WCF 服务通过 HTTP 响应,但不通过 HTTPS 响应