3

我正在使用 Boost ASIO 库来编写 TCP 客户端程序。

当您连接时,该协议以横幅行开头,然后是“\r\n”我可以随时发送命令,就像 smtp。

但是,服务器也可以在我不要求时向我发送数据并且它以 '\r\n' 终止

我有这样一行来读取和解析初始连接横幅,这意味着,当我得到“\r\n”时停止阅读。

boost::asio::streambuf response_;
...
boost::asio::async_read_until(socket_, response_, "\r\n",
            boost::bind(&PumpServerClient::HandleReadBanner, this,
                boost::asio::placeholders::error));

但是在不同的时间我想能够问这个问题,有可用的数据吗?如果有,请阅读它直到“\r\n”。我觉得我需要一个窥视功能,但我看不到它在哪里。

好的,也许我可以再次调用 async_read_until。但是考虑一下……它永远不会结束。继续阅读调试出现一次。显然,它一直在等待完成,但永远不会完成。

void client::HandleReadRequest(const boost::system::error_code& err)
{
    if (!err){
        // Got some data, print it out
        std::ostringstream ss;
        ss << &response_;

        std::cout << ss.str() << std::endl;

         // Keep reading...
        boost::asio::async_read_until(socket_, response_, "\r\n",
          boost::bind(&client::HandleReadRequest, this, boost::asio::placeholders::error));

        std::cout << "keep reading" << std::endl;
    }
    else
    {
        std::cout << "Error: " << err.message() << "\n";
    }
}

好的,我想我现在明白了。我没有看一个足够完整的例子来作为我的代码的基础。

它看起来像调用:

boost::asio::async_read_until(socket_, response_, "\r\n", boost::bind(&client::HandleReadRequest, this, boost::asio::placeholders::error)); 表示当response_缓冲区中出现\r\n时,会调用函数HandleReadRequest。我只需要调用 async_read_until 一次。除非调用了写请求,否则我需要再次读取......看起来......好吧,我至少现在可以工作了。

4

2 回答 2

4

从浏览文档开始,我将使用socket_base::bytes_readable,如下所示:

boost::asio::ip::tcp::socket socket(io_service); 
...
boost::asio::socket_base::bytes_readable command(true);
socket.io_control(command);
std::size_t bytes_readable = command.get();
于 2009-12-15T22:51:29.723 回答
2

通常在 asio 中使用异步操作时,不需要“窥视”。当数据可用时,asio 将通过调用您提供的处理函数来告诉您。如果尚未调用您的处理程序,则没有可用数据。

如果你“偷看”套接字,我怀疑它不会像你期望的那样工作,因为数据将被 asio 读取并在可用时立即传递给读取处理程序,它只会“准备好读取”调用处理程序时的一小段时间。尽管只要没有async_read在套接字上启动它就可以工作。

在您的情况下async_read_until,您可能只想在调用读取处理程序时发布另一个读取请求。

于 2009-12-15T22:54:13.120 回答