【问题标题】:how to handle https request response on native socket asynchronously in C++如何在 C++ 中异步处理本机套接字上的 https 请求响应
【发布时间】:2015-08-17 11:56:52
【问题描述】:

在我的 C++ 应用程序中,我使用 epoll 实现了“Reactor”设计模式。我有 Reactor 类,我在其中注册了所有 Fd(socketFd/EventFd/TimerFd)和相应的处理程序函数。当应用程序启动时,我运行 Reactor 的事件循环。

在这个应用程序中,我必须发送 https 请求并处理收到的 https 响应。现在我正在使用CurlPP(libcurl c++ 包装器)发送这个 https 请求。但这些是同步和阻塞调用。这妨碍了我的表现。

现在我想使用我的 Reactor 类异步处理这些 https 请求/响应。为此,我将创建本机套接字并连接到 http 服务器。在 Reactor 中注册这个 socketFd 和相应的处理函数。

要在本机套接字上发送 https 请求,我需要一些库,它将 https 有效负载作为输入并返回 https(SSL 加密)http 请求。这样我就可以直接在本机套接字上编写这个 https 请求了。

处理 https 响应的方法相同。套接字上的 read/recv 调用将返回缓冲区。我需要一些库来接收这个缓冲区并给我接收到的 https 有效负载。

我确实检查了 libcurl 中可用的 API。但是 libcurl 没有提供这样的功能。它确实具有多句柄功能,但套接字的控制是由 libcurl 本身来控制的。

您能否推荐任何可以为我提供此类功能的库?另外,如果您有任何其他方法来异步处理这些 https 请求,那么也请提出建议。

【问题讨论】:

    标签: c++ sockets asynchronous


    【解决方案1】:

    要在本机套接字上发送 https 请求,我需要一些库,它将 https 有效负载作为输入并返回给我 https(SSL 加密)http 请求。这样我就可以直接在本机套接字上编写这个 https 请求了。

    处理 https 响应的方法相同。套接字上的 read/recv 调用将返回缓冲区。我需要一些库来接收这个缓冲区并给我接收到的 https 有效负载。

    没有。这会给您带来巨大的痛苦,并且永远无法正常工作。 SSL 不是块加密协议。这是一个 stream 协议。您将永远无法以这种方式获得有效的实现。您可能会得到一个似乎在大多数情况下都可以正常工作的设备,但随后您会发现它会在例如本地发送触发 SSL 重新协商时中断。

    您必须将 SSL 视为一个黑匣子,绝不可尝试查看。因为 SSL 连接两个双向流协议,所以黑盒有四个(名义上的)端口:

    1. 它有一个“加密数据输入”端口。当你从套接字接收数据时,你必须把它交给这个端口。

    2. 它有一个“加密数据输出”端口。当从该端口发送数据时,您必须将其发送到套接字。

    3. 它有一个“纯文本输入”端口。当你想向对方发送数据时,你必须把它发送到这个端口。

    4. 它有一个“明文输出”端口。当数据被解密时,它会在这个端口上给你。

    必须将这些端口视为独立的,并且您不得假设,例如,在您将数据提供给“纯文本输入”端口之后,数据就会出来“加密数据输出”端口。为什么?因为引擎可能仍在等待重新协商完成。您不得假设因为您将数据提供给“加密数据输入”端口,这意味着数据将从“明文输出”端口输出。为什么?因为它可能是协商数据,也可能是区块的一部分。

    你把问题想错了。回到绘图板上,请记住,您正在实现一个双向字节流协议,该协议位于另一个双向字节流协议之上。

    这是通过数十年的痛苦经验获得的知识 - 忽略它,后果自负。

    【讨论】:

    • 您关于 SSL 的观点是完全正确的,但我不明白为什么它与 OP 所说的相矛盾。简而言之 - 将手动接收/发送与 (Open)SSL 相结合是完全可能的(它只需要比 OP 最初指定的要小心一点,请参阅您的第 1-4 点)。
    • 这需要完全不同的思考问题。如果您从“数据通过并被加密/解密”的角度开始考虑它,您将编写会失败的代码。
    • 对,但是恕我直言,“数据通过”和“输入一些数据 - 看看哪里/如果你有一些数据输出”之间的区别并不大(并且不会影响程序的其余部分太多了)。真正重要的是一种将数据从 HTTP 请求转换为加密 SSL(反之亦然)的方法,如何做到这一点是另一回事。
    • @No-BugsHare 哦,我完全不同意。如果您的软件采用“数据通过”模型设计并且必须对其进行修复,则基本上可能需要完全重写。例如,想象一个使用两个线程的实现,一个用于加密出站数据,一个用于解密入站数据。这很可能无法挽救。
    • 好吧,如果有人围绕这个概念构建了整个应用程序(并且围绕这样一个低级概念构建一个完整的应用程序而不留下任何灵活性是一个非常糟糕的主意,无论 SSL 或其他什么) - 是的.然而,我的观点是,如果整体设计是可靠的,并且应该尽可能减少耦合,那么 SSL(以及该规模的其他任何东西)只是一小块拼图,只要它不影响其他拼图 - 重写一小块拼图没什么大不了的(好吧,这将需要 2 天 - 对于任何大型项目来说,这只是宏观架构中的花生)。
    【解决方案2】:

    快速而肮脏的方式:

    一种方法是使用相同的 libcurl 在单独的线程中发出这些请求(libcurl 线程将回复报告回主线程,其中处理回复)。如果性能成为问题,线程池应该会有所帮助。话虽如此,这种线程方法不会为您提供绝对最佳的性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多