提升 Asio SSL 无法第二次接收数据(第一次确定)
Boost Asio SSL not able to receive data for 2nd time onwards (1st time OK)
我正在为简单的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()
。
详情请阅读(注意警告(链接
SSL_clear(( 重置 SSL 对象以允许另一个连接。但是,重置操作会保留上次会话的多个设置(其中一些设置是在上次握手期间自动进行的( .........
警告
SSL_clear(( 重置 SSL 对象以允许另一个连接。但是,重置操作会保留上次会话的多个设置(其中一些设置是在上次握手期间自动进行的(。它仅对共享这些设置的完全相同的对等方的新连接有意义,如果该对等方在连接之间更改其设置,则可能会失败。使用序列SSL_get_session(3(;SSL_new(3(;SSL_set_session(3(;SSL_free(3(而是为了避免此类故障(或简称SSL_free(3(;SSL_new(3( 如果不需要会话重用(。
关于 SSL 关闭问题,链接解释提升 asio SSL 关闭的工作原理。
在 Boost.Asio 中,如果出现错误或一方发送和接收了close_notify消息,则认为 shutdown(( 操作已完成。
如果您查看boost.asio(1.68(源代码boost\asio\ssl\detail\impl\engine.ipp,它显示了boost.asio如何执行SSL关闭,并且当有数据要读取或SSL关闭预期未收到时,会发生stream_truncated
。
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 关闭例程可能会调用 opensslSSL_shutdown()
两次,如果第一个返回 0,openssl 文档允许它,但如果第一个返回 0,建议调用SSL_read()
进行双向关闭SSL_shutdown()
。
有关详细信息,请阅读链接。
我遇到了类似的问题,第二次我的异步接受总是失败,会话 ID 未初始化。
我解决了在上下文或调用SSL_CTX_set_session_id_context的问题 使用上下文选项SSL_SESS_CACHE_OFF和SSL_OP_NO_TICKET设置上下文缓存模式。
这是我对别人问题的美分。
我设法通过将"ssl::stream"套接字切换到"boost::optional",然后在每次套接字关闭和关闭时添加"SSL_Socket.emplace(io_context,oSSLContext("来解决问题。
在"无法实现 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>重新连接到服务器"时,大功劳。他的声明">最纯粹的解决方案是不重复使用流/套接字对象"摇滚!节省我的时间。
谢谢。
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 在 C++ AMP 数组中复制数据多少次?
- 我必须构建我的项目 2 次,第一次失败,因为它无法打开库
- 是什么导致我的循环在第一次迭代中运行得更慢
- QLibrary 函数在第一次调用时工作缓慢
- 第一次尝试使用new动态创建结构数组,程序挂起没有错误
- 为什么第一次迭代后的指针指向随机值?
- 如果我使用同一个密钥推送用户数据两次,会发生什么
- 如何防止GUI挂起,同时允许第二次操作与Qt中的第一次操作一起执行
- LAPACK函数在第一次迭代后变慢
- 为什么 Boost unordered_map 在第一次插入时需要太多时间?
- EGL 在第一次 opengl 函数调用时崩溃
- 提升 Asio SSL 无法第二次接收数据(第一次确定)
- 数组仅在第一次返回错误值
- C++程序在第一次尝试时会给出垃圾,但如果它捕获异常并重试,则会给出适当的值
- 为什么字符串的长度在第一次读取文件时相差 1?
- 为什么 new 第一次分配 1040 个额外的字节?
- 插入多音符:在该值的第一次发生之前,而不是在上次发生之后
- 丢失的数据包仅在第一次运行中发生
- 接收在第一次读取之前被发送到串口的数据