io_service :: run()永远不会返回

时间:2015-11-06 20:19:34

标签: c++ boost boost-asio

UPDATE_2 我最终使用

if (socket.available())

如果套接字上有数据,我会读取它,如果没有,我跳过。

已更新 我有个问题。 io_service :: run()永远不会在以下代码片段中返回:

客户方:

#include <iostream>

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>

using namespace std;
using boost::asio::ip::tcp;

void handler(
    const boost::system::error_code &error,
    size_t bytes_transferred
)
{
    cout << "Handler called" << endl;
}

int main()
{
    //establishing connection
    boost::asio::io_service io_service;
    tcp::socket socket(io_service);
    tcp::resolver resolver(io_service);
    tcp::resolver::query query("localhost", "17073");
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    boost::asio::connect(socket, endpoint_iterator);
    //connection established

    boost::array<char, 128> buf;
    socket.async_read_some(boost::asio::buffer(buf), boost::bind(handler, _1, _2));

    //async_read_some returns

    io_service.run();       //I suppose that handler_for_async_response is called if:
                            //1) EOF was read (no data read twice) by async_read_some
                            //2) something was in fact read
                            //is this right?

    //execution does not get here

    return 0;
}

服务器端(仅接受连接并在那里无所事事地挂起):

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>

using namespace std;
using boost::asio::ip::tcp;

int main()
{
    //establishing connection
    boost::asio::io_service io_service;
    tcp::socket             socket(io_service);
    tcp::acceptor           acceptor(io_service, tcp::endpoint(tcp::v4(), 17073));

    acceptor.accept(socket);

    std::cout << "connection has been established!" << std::endl;
    //connection established

    while (true)
    {
        //do nothing
    }

    return 0;
}

我要做的是查看套接字上是否有任何数据。如果是 - 那么请阅读它,如果没有 - 那么继续前进。

PS我打算从套接字读取并写入它。

无论如何,我是提升:: asio的新手,我希望有人可以告诉我我做错了什么。谢谢!

1 个答案:

答案 0 :(得分:2)

更新使用代码回复更新的问题:

您的客户端正在等待128个字节或EOF。这些都没有,因为服务器没有发送任何东西(但是没有关闭连接)。

要么改变

  1. 客户,例如

    • 不要等到实际数据到达

      boost::array<char, 0> buf;
      
    • 或者socket.cancel()之后deadline_timer(或者等等。

  2. 服务器,例如用真正的套接字写

  3. 替换无限循环

    这是一个样本

    <强> Live On Coliru

    #include <boost/array.hpp>
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
    
    using boost::asio::ip::tcp;
    using namespace std;
    
    #ifdef SERVER
        int main()
        {
            //establishing connection
            boost::asio::io_service io_service;
            tcp::socket             socket(io_service);
            tcp::acceptor           acceptor(io_service, tcp::endpoint(tcp::v4(), 17073));
    
            acceptor.accept(socket);
    
            std::cout << "connection has been established!" << std::endl;
            //connection established
    
            socket.send(boost::asio::buffer(std::string("Hello world\n")));
        }
    #else
        void handler(
            boost::array<char, 128> const& buf,
            const boost::system::error_code &error,
            size_t bytes_transferred
        )
        {
            cout << "Handler called (" << error.message() << "): "  << endl;
            cout.write(buf.data(), bytes_transferred);
        }
    
        int main()
        {
            //establishing connection
            boost::asio::io_service io_service;
            tcp::socket socket(io_service);
            tcp::resolver resolver(io_service);
            tcp::resolver::query query("127.0.0.1", "17073");
            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            boost::asio::connect(socket, endpoint_iterator);
            //connection established
    
            boost::array<char, 128> buf;
            socket.async_read_some(boost::asio::buffer(buf), boost::bind(handler, boost::ref(buf), _1, _2));
    
            //async_read_some returns
    
            io_service.run();       //I suppose that handler_for_async_response is called if:
                                    //1) EOF was read (no data read twice) by async_read_some
                                    //2) something was in fact read
                                    //is this right?
    
            //execution does not get here
    
            return 0;
        }
    #endif
    

    打印:

    //(server)
    connection has been established!
    //(client)
    Handler called (Success): 
    

    Hello world

    您必须决定同步或异步编程。

    在这种情况下,我认为您可能真的在寻找tcp::istream

    当任务用完时运行返回:

      

    run()函数阻塞,直到所有工作完成,并且没有更多处理程序要调度,或者直到io_service已停止。

         

    多个线程可以调用run()函数来设置一个线程池,io_service可以从中执行处理程序。在池中等待的所有线程都是等效的,io_service可以选择其中任何一个来调用处理程序。

         

    run()函数的正常退出意味着io_service对象停止(stopped()函数返回true)。除非事先致电run(),否则对[{1}},run_one()poll()poll_one()的后续调用将立即返回。

    所以你还有其他工作待定(io_service :: work?)。检查一下。使您的代码成为SSCCE,我们将能够看到更多。