是否可以在使用 Boost::asio 之前从套接字读取后执行async_handshake

Is it possible to do async_handshake after reading from socket prior using Boost::asio?

本文关键字:读取 套接字 执行 handshake async asio Boost 是否      更新时间:2023-10-16

我有一个boost::asio::ssl::stream<boost::asio::ip::tcp::socket>类型化的套接字。当 boost 第一次接受与此套接字的连接时,我想偷看一些字节。但是,偷看不是您可以正确/安全地做的事情。所以我读取我需要的字节并将它们放在缓冲区中。

typedef socket_type boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
void OnAccept(std::shared_ptr<socket_type> socket)
{
    boost::asio::mutable_buffers_1 sslBuffer(m_Buffer.data(), m_Buffer.size());
    // I'm going to read 4 bytes from the socket.
    boost::system::error_code ec;
    std::size_t readBytes = boost::asio::read(socket->next_layer(), boost::asio::buffer(sslBuffer, 4), ec);
    if(ec) { Stop(); return; } // pseudo
    // Check the bytes I read in the buffer
    socket->async_handshake(boost::asio::ssl::stream_base::server, sslBuffer, &handler);
}

此时,将调用async_handshake的处理程序,但它会告诉我它从 ssl 获得了unexpected message错误代码。这是有道理的:它正在握手的消息可能缺少前 4 个字节!

我该怎么做才能为async_handshake提供适当的缓冲区,通知它其中已经有有效的 4 个字节?

在调查了async_handshake缓冲区重载方法的实现之后,缓冲区似乎必须已经读入了握手。

尝试过,但仍然遇到问题,我不断收到一个错误代码,说SSL版本不正确。我知道这不是问题,因为不使用async_handshake的缓冲重载工作正常!

然后,解决方案是限制缓冲区参数的大小。

typedef socket_type boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
void OnAccept(std::shared_ptr<socket_type> socket)
{
    const uint bytesToPeek = 4;
    boost::asio::mutable_buffers_1 sslBuffer(m_Buffer.data(), m_Buffer.size());
    // I'm going to read 4 bytes from the socket.
    boost::system::error_code ec;
    std::size_t readBytes = boost::asio::read(socket->next_layer(), boost::asio::buffer(sslBuffer, bytesToPeek), ec);
    if(ec) { Stop(); return; } // pseudo
    // Check the bytes I read in the buffer
    // Read in the rest of the handshake.
    std::size_t bytesOfHandshake = socket->next_layer().read_some(boost::asio::buffer(sslBuffer+bytesToPeek, 4000));
    bytesOfHandshake += bytesToPeek;
    // Finish the handshake.
    socket->async_handshake(boost::asio::ssl::stream_base::server, boost::asio::buffer(sslBuffer, bytesOfHandshake), &handler);
}

请注意,其中的readread_some调用也应async 进行。我只是想在没有处理程序的情况下演示答案。