c++ - io_service::run() 永不返回

标签 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 我打算同时从套接字读取并写入它。

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

最佳答案

UPDATE 用代码回应更新的问题:


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

要么改变

  1. 客户,例如

    • 不要等待实际数据到达

      boost::array<char, 0> buf;
      
    • 或者在 deadline_timer 之后(大约如此。

  2. 服务器,例如用真正的套接字写入替换无限循环

这是一个例子

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


当任务用完时运行返回:

The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.

Multiple threads may call the run() function to set up a pool of threads from which the io_service may execute handlers. All threads that are waiting in the pool are equivalent and the io_service may choose any one of them to invoke a handler.

A normal exit from the run() function implies that the io_service object is stopped (the stopped() function returns true). Subsequent calls to run(), run_one(), poll() or poll_one() will return immediately unless there is a prior call to reset().

所以您还有其他待处理的服务工作(io_service::work?)。检查一下。让您的代码成为 SSCCE,我们将能够看到更多内容。

关于c++ - io_service::run() 永不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33575080/

相关文章:

c++ - C++ 中字符串类型的枚举类

c++ - 集成三个变量的函数 C++

c++ - Boost.Coroutine 不使用分段堆栈

c++ - boost::odeint 在成员类中调用

c++ - 如何使用 boost asio 通过 UDP 套接字发送 std::vector of unsigned char?

c++ - 让 Boost 1.68 在 Ubuntu 18.04 上运行

c++ - 多个提升 io_service 用于单独线程上的多个网卡

c++ - 更新 CMake(似乎)破坏了我的程序

c++ - [Boost]::DI 从注入(inject)器创建唯一的 shared_ptr 对象

c++ - 在 Qt 中创建一个简单的表格单元格