Boost.Asio: 从 SSL-Socket 读取输入导致数据不完整
Boost.Asio: Reading input from SSL-Socket results in incomplete data
我有一个名为 NIUserSession
的 class,它处理与客户端的 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) 数据:
服务器输出:
Bytes transfered: 169
Message: {
如您所见,传输了 169 个字节,但输出中仅出现 1 个字符。我想我对 boost::asio::streambuf
做错了什么(我以前从未使用过)。
这一行:
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);
我有一个名为 NIUserSession
的 class,它处理与客户端的 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) 数据:
服务器输出:
Bytes transfered: 169
Message: {
如您所见,传输了 169 个字节,但输出中仅出现 1 个字符。我想我对 boost::asio::streambuf
做错了什么(我以前从未使用过)。
这一行:
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);