Ответ 1
Один из способов устранения кода ошибки с дешифровкой или неудачей записи из второго контекста:
a) внутри вызова обработчика stdin:
ssl::stream<tcp_socket>::lowest_layer()::shutdown(tcp::socket::shutdown_receive)
b) это приводит к выполнению обратного вызова async_read_some()
с кодом ошибки "короткого чтения"
c) в этом обратном вызове в соответствии с условием "ошибка" async_shutdown()
вызывается:
// const boost::system::error_code &ec
if (ec.category() == asio::error::get_ssl_category() &&
ec.value() == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) {
// -> not a real error:
do_ssl_async_shutdown();
}
d) обратный вызов async_shutdown()
выполняется с кодом ошибки "короткого чтения", откуда мы наконец вызываем:
ssl::stream::lowest_layer()::close()
Эти шаги приводят к отключению подключения без каких-либо странных сообщений об ошибках на стороне клиента или сервера.
Например, при использовании openssl s_server -state ...
в качестве сервера он сообщает об отключении:
SSL3 alert read:warning:close notify DONE shutting down SSL CONNECTION CLOSED ACCEPT
(последняя строка состоит в том, что команда принимает новые соединения)
Alternative
Вместо lowest_layer()::shutdown(tcp::socket::shutdown_receive)
мы также можем назвать
ssl::stream<tcp_socket>::lowest_layer()::cancel()
чтобы инициировать надлежащее завершение работы. Он имеет тот же эффект, т.е. Дает выполнение запланированного обратного вызова async_read_some()
(но с кодом ошибки operation_aborted
). Таким образом, оттуда можно называть async_shutdown()
:
if (ec.value() == asio::error::operation_aborted) {
cout << "(not really an error)\n";
do_async_ssl_shutdown();
}