【问题标题】:Sending TCP data without recieving (boost asio)发送 TCP 数据而不接收(增强 asio)
【发布时间】:2016-11-04 14:43:22
【问题描述】:

我正在学习 boost 的 asio 教程。我正在调查他们的chat example。更具体地说,我试图将他们的chat client 从发送者+接收者拆分为发送者和接收者,但我看到了一些我无法解释的行为。

设置包括:

boost::asio::io_service io_service;
tcp::resolver::iterator endpoint = resolver.resolve(...);

boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
boost::asio::async_connect(socket, endpoint, bind(handle_connect, ... ));

发送部分实际上包括:

while (std::cin.getline(str))
  io_service.post( do_write, str );

void do_write (string str)
{
    boost::asio::async_write(socket, str, bind( handle_write, ... ));
}

接收部分由

组成
void handle_connect(...)
{
    boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}

void handle_read(...)
{
    std::cout << read_msg_;
    boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}

如果我注释掉handle_connect 的内容以隔离发送部分,我的其他客户端(使用原始代码编译)不会收到任何内容。如果我还原,则注释掉handle_read 的内容,我的其他客户端只收到第一条消息。

为什么必须调用async_read() 才能调用post()async_write()

上面链接了完整的未修改代码。

【问题讨论】:

    标签: tcp boost-asio


    【解决方案1】:

    这里的问题是,您的io_service 已经用完了,甚至在您开始发送聊天消息之前就停止处理请求。

    如果您注释掉handle_connect 的主体,那么它唯一要做的工作就是调度handle_connect 处理程序,然后在连接完成后执行它。

    std::size_t scheduler::run(asio::error_code& ec)
    {
      .....
      mutex::scoped_lock lock(mutex_);
    
      std::size_t n = 0;
      for (; do_run_one(lock, this_thread, ec); lock.lock())
        if (n != (std::numeric_limits<std::size_t>::max)())
          ++n;
      return n;
    }
    

    所以,你必须在它的操作队列中提供一些东西。这是在原始代码中使用 handle_read_header 处理程序完成的,因为此处理程序始终需要服务,直到客户端从服务器获取某些内容。

    您可以通过将work 提供给io_service 来做您想做的事情。

    asio::io_context io_context;
    asio::io_context::work wrk(io_context); // make `run` run forever
    
    tcp::resolver resolver(io_context);
    tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
    
    chat_client c(io_context, endpoints);
    
    asio::thread t(boost::bind(&asio::io_context::run, &io_context));
    

    【讨论】:

    • 你完全正确。我将这项工作添加到 io_service 并且效果很好。谢谢!
    猜你喜欢
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2020-06-22
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多