c++ - Boost Asio SSL 第二次以后无法接收数据(第一次正常)

标签 c++ ssl boost openssl boost-asio

我正在为简单的 RESTful 服务器开发 Boost Asio 和 Boost Beast。对于普通的 HTTP 和 TCP 套接字,它工作得很好。我用 JMeter 对其进行了负载测试,一切正常。

我尝试添加 SSL 套接字。我设置了“ssl::context”并调用了“async_handshake()”——与普通套接字相比,SSL 的额外步骤。它仅在第一次使用。客户端可以与我(服务器)连接,我也可以通过 'boost::beast::http::async_read()' 接收数据。

因为这是 RESTful,所以连接会在请求和响应后断开。我调用“SSL_Socket.shutdown()”,然后调用“SSL_Socket.lowest_layer().close()”来关闭 SSL 套接字。

当下一个传入请求时,客户端能够与我(服务器)连接。我调用了“SSL_Socket.async_handshake()”,然后调用了“boost::beast::http::async_read()”。但是这次我无法接收到任何数据。但已成功建立连接。

有人知道我错过了什么吗?

非常感谢!

最佳答案

如果要重用流实例,需要用openssl lib函数操作SSL_Socket.native_handle()。 ssl 关闭后,在开始新的 ssl 握手之前使用 SSL_clear()

请阅读(注意警告)link详情

SSL_clear() resets the SSL object to allow for another connection. The reset operation however keeps several settings of the last sessions (some of these settings were made automatically during the last handshake) .........

WARNINGS

SSL_clear() resets the SSL object to allow for another connection. The reset operation however keeps several settings of the last sessions (some of these settings were made automatically during the last handshake). It only makes sense for a new connection with the exact same peer that shares these settings, and may fail if that peer changes its settings between connections. Use the sequence SSL_get_session(3); SSL_new(3); SSL_set_session(3); SSL_free(3) instead to avoid such failures (or simply SSL_free(3); SSL_new(3) if session reuse is not desired).

关于 ssl 关闭问题,link解释 boost asio ssl shutdown 是如何工作的。

In Boost.Asio, the shutdown() operation is considered complete upon error or if the party has sent and received a close_notify message.

如果您查看 boost.asio (1.68) 源代码 boost\asio\ssl\detail\impl\engine.ipp,它显示了 boost.asio 如何执行 ssl 关闭和 stream_truncated当有要读取的数据或未收到对等方预期的 ssl 关闭时发生

int engine::do_shutdown(void*, std::size_t)
{
  int result = ::SSL_shutdown(ssl_);
  if (result == 0)
    result = ::SSL_shutdown(ssl_);
  return result; 
} 
const boost::system::error_code& engine::map_error_code(
    boost::system::error_code& ec) const
......
// If there's data yet to be read, it's an error.
if (BIO_wpending(ext_bio_))
{
    ec = boost::asio::ssl::error::stream_truncated;
    return ec;
}
......
// Otherwise, the peer should have negotiated a proper shutdown.
if ((::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN) == 0)
{
    ec = boost::asio::ssl::error::stream_truncated;
}
}

您还可以看到 boost.asio ssl 关闭例程可能会调用 openssl SSL_shutdown() 两次,如果第一次返回 0,openssl 文档允许它但建议调用 SSL_read() 到如果第一个 SSL_shutdown() 返回 0,则执行双向关闭。

阅读link了解详情。

关于c++ - Boost Asio SSL 第二次以后无法接收数据(第一次正常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50693708/

相关文章:

c++ - 带有参数列表的父类(super class)方法 <superclass> 与专用列表一起使用

c# - 从 C# 调用 DLL 时,为什么小结构会错位函数参数?

c++ - 指向主窗口的 QPointer

python-3.x - 忽略 SSL 证书验证有什么影响?

wordpress - wordpress ssl 出现 404 错误

c++ - 将 std::vector<size_t> 与不同的整数类型一起使用总是安全的吗?

facebook - 既然我们已经转移到 https,我们能否获得针对 http 站点的 fb 评论?

c++ - 内存映射文件和最大文件大小

c++ - C++中有排序集合吗?

c++ - 使用整数索引访问 boost::graph 中的特定边