2016-11-03 75 views
1

我正在通过boost的asio教程工作。我正在调查他们的chat example。更具体地说,我试图将他们的chat client从发送者+接收者分割为发送者和接收者,但是我看到一些我无法解释的行为。发送TCP数据,无需接收(升压asio)

的设置包括:

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, ...)); 

发送部有效conisists的:

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()

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

回答

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处理程序完成的,因为此处理程序始终需要进行服务,直到客户机从服务器获取某些内容为止。

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

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)); 
+0

你是对的。我将这些工作添加到了io_service中,并且效果很好。谢谢! – Stewart