Я проверил пример форсирования и много тестировал, но я думаю, что async_read
не запускается должным образом, когда пакет (полученные данные) меньше или больше ожидаемого буфера.
Там пример сервер и клиент SSL на boost.org. В примере клиента после того, как рукопожатие выполнено, вызывается send_request()
, а затем send_request()
с точной длиной отправленного текста. Что произойдет, если send_request()
не знает о длине пакета? Для этого есть три ситуации (под длиной буфера я подразумеваю length
аргумент в boost::asio::buffer(reply_, length)
):
Длина пакета равна длине буфера Нет проблем, мы получили пакет.
Длина пакета> длина буфера Мы получаем столько же, сколько длина пакета, то, что осталось, получено в другой ход, проблема в том, что мы не можем получить остальную часть пакета, помещая еще один send_request()
в лямбда-тело, остатки получат, когда будет вызван другой send_request()
(и т. д.):
void receive_response(std::size_t length)
{
boost::asio::async_read(
socket_,
boost::asio::buffer(reply_, length),
[this](const boost::system::error_code& error, std::size_t length)
{
if (!error)
{
std::cout << "Reply: ";
std::cout.write(reply_, length);
std::cout << "\n";
receive_response(length); <---------- this one
}
...
}
);
}
Длина пакета <длина буфера </strong> Я немного изменил лямбда-квитирование, чтобы можно было смоделировать этот, как в следующем фрагменте кода, я также изменил методы receive_response()
и send_request()
, чтобы они не вызывали друг друга. Я ожидал, что лямбда async_read
(в receive_response()
) будет вызвана после двух async_write
(в send_request()
) заполнения буфера, но этого не произошло.
void handshake()
{
socket_.async_handshake(
boost::asio::ssl::stream_base::client,
[this](const boost::system::error_code& error)
{
if (!error)
{
receive_response(10); //Trigger async_read for length 10
send_request(); //Send a string of length 5
send_request(); //Send a string of length 5
}
...
}
);
}
Можно предположить используя async_read_some()
. Я тоже это проверял. К счастью, он вызывается первым send_request()
, но второй send_request()
не вызывает async_read_some()
лямбду (я поместил еще один receive_response()
в тело лямбды, чтобы сделать al oop).
void receive_response(std::size_t length)
{
socket_.async_read_some(
boost::asio::buffer(reply_, length),
[this](const boost::system::error_code& error, std::size_t length)
{
...
receive_response(length);
...
}
);
}