Boost.Asio:从SSL-Socket读取输入会导致数据不完整

时间:2016-06-25 12:57:54

标签: c++ boost boost-asio

我有一个名为NIUserSession的类,它处理与客户端的SSL加密连接。就是这样,虽然我删除了与我的问题无关的所有内容:

typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;


class NIUserSession
{
public:

    /*....*/
    void readUntil(std::string until);
    /*....*/

private:

    /*....*/
    void readHandler(const boost::system::error_code& error, std::size_t bytes_transferred);
    ssl_socket socket_;
    boost::asio::streambuf readBuffer;
    /*....*/

};

void NIUserSession::readUntil(std::string until)
{
    boost::asio::async_read_until(this->socket_, this->readBuffer, until, boost::bind(&NIUserSession::readHandler,
                                                                                      this,
                                                                                      boost::asio::placeholders::error(),
                                                                                      boost::asio::placeholders::bytes_transferred()));
}

void NIUserSession::readHandler(const boost::system::error_code &error, std::size_t bytes_transferred)
{
    if(!error)
    {
        std::cout << "Bytes transfered: " << bytes_transferred << std::endl;
        this->readBuffer.commit(bytes_transferred);
        std::istream istrm(&this->readBuffer);
        std::string message;
        istrm >> message;

        std::cout << "Message: " << message << std::endl;
    } else {
        // ...
    }
}

现在客户端连接,ssl握手等,然后从NIUserSession内执行此行:

this->readUntil("<EOF>");

服务器现在应该等到客户端发送消息并以<EOF>结束消息。

从我的客户端应用程序中,我发送以下(JSON)数据:

The json-data

服务器输出:

Bytes transfered: 169
Message: {

如您所见,传输了169个字节,但输出中只显示 1 字符。我想我在做boost::asio::streambuf(我以前从未使用过它)的错误。

1 个答案:

答案 0 :(得分:1)

这一行:

istrm >> message;

读取由流中的空格分隔的字符串。第一个“{”是由空格分隔的字符串。您只需要继续阅读istrm

不是使用operator>>,而是使用boost::asio::buffers_begin()将指定的字节数复制到字符串中以获取随机访问迭代器,然后使用两个迭代器构造字符串。这看起来像这样(未经测试):

const auto bufferIterator = boost::asio::buffers_begin(this->readBuffer.data());
const std::string message(bufferIterator, bufferIterator + bytes_transferred);
this->readBuffer.consume(bytes_transferred);