我想使用非常方便的Boost async_read_until来读取消息,直到获得\r\n\r\n
分隔符。直到在boost :: asio :: streambuf中使用字符串分隔符
我喜欢使用这个分隔符,因为它很容易使用telnet进行调试并制作多行命令。我只用两条新的线表示命令结束。
我打电话async_read_until
这样的:
void do_read()
{
boost::asio::async_read_until(m_socket,
m_input_buffer,
"\r\n\r\n",
std::bind(&player::handle_read, this, std::placeholders::_1, std::placeholders::_2));
}
而且我的处理程序看起来像这样的时刻:
void handle_read(boost::system::error_code ec, std::size_t nr)
{
std::cout << "handle_read: ec=" << ec << ", nr=" << nr << std::endl;
if (ec) {
std::cout << " -> emit on_disconnect\n";
} else {
std::istream iss(&m_input_buffer);
std::string msg;
std::getline(iss, msg);
std::cout << "dump:\n";
std::copy(msg.begin(), msg.end(), std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl;
do_read();
}
}
我想用std::getline
就像例子,但我的系统上这样下去\r
字符。正如你所看到的,如果我连接到服务器,写hello
加上两个CRLF,我得到这个转储服务器端:
handle_read: ec=system:0, nr=9
dump:
104, 101, 108, 108, 111, 13,
^^^ \r here
顺便说一句,这也将保持在缓冲区中的下一个新行。所以我认为std::getline
不会为我完成这项工作。
我搜索一个方便有效的方式来从boost::asio::streambuf
读取,直到我得到这个\r\n\r\n
定界符。由于我一次只使用一次async_read_until
,当处理程序被调用时,缓冲区应该具有精确和完整的数据不是吗?你有什么建议阅读,直到我得到\r\n\r\n
?
如果实际的缓冲区被读到'cmd1 \ r \ n \ r \ ncmd2 \ r \ n \ r \ n'怎么办?只有当发送第三个命令时,第二个命令才会被解析。所以我们需要循环,而有一些数据可用不是吗? – markand
@markand No.最优雅的解决方案是发出另一个'async_read_until'操作。由于缓冲区已经包含分隔符,因此在尝试I/O之前会检测到完成条件,并且完成处理程序将准备好运行。 –
啊,你是对的,非常感谢:) – markand