使用 boost::asio::async_read 失败,但 boost::asio::read 有效(正在使用 io_stream.run_one())

发布于 2024-12-20 17:25:42 字数 1086 浏览 0 评论 0原文

我有一个本机 posix 套接字,我尝试使用 boost::asio::async_read 异步读取它。但是,当我这样做时:

// io_stream and fd are passed by reference to this function
asio::posix::stream_descriptor stream(io_stream);
stream.assign(fd);

boost::system::error_code ec;

asio::async_read(stream, buffer,
                 asio::transfer_at_least(1),
                 boost::bind(doRead,
                             asio::placeholders::error,
                             asio::placeholders::bytes_transferred));
size_t count = io_service.run_one(ec);

count 变量设置为 0,并且 doRead 处理程序永远不会被调用,并且 ec 不包含错误。但是,如果我将异步读取替换为同步读取:

size_t count = asio::read(stream, buffer,
                          asio::transfer_at_least(1));

这会起作用,并且我会在计数变量中得到预期的数据量。

我的测试用例使用由“int pipeline(int pipelinefd[2]);”创建的 fd并通过 asio::async_read 很好地传递数据,所以我认为这可能是几个选项:

  • 我传递的本机描述符在某种程度上与 async_read 不兼容,因此它会默默地失败。我尝试过通过阻塞打开和关闭来创建它,但没有成功。
  • io_service 和 posix::stream_descriptor 没有连接,因此 io_service 永远不会尝试运行读取。这可能是由于我通过引用传递 io_service 造成的吗? (就此而言,也在几个线程内?)

I have a native posix socket which i am trying to asynchronously read from using boost::asio::async_read. However when I do this:

// io_stream and fd are passed by reference to this function
asio::posix::stream_descriptor stream(io_stream);
stream.assign(fd);

boost::system::error_code ec;

asio::async_read(stream, buffer,
                 asio::transfer_at_least(1),
                 boost::bind(doRead,
                             asio::placeholders::error,
                             asio::placeholders::bytes_transferred));
size_t count = io_service.run_one(ec);

The count variable is set with 0 and the doRead handler is never called and ec contains no errors. However if I replace the async read with a synchronous read:

size_t count = asio::read(stream, buffer,
                          asio::transfer_at_least(1));

This works and I get the expected amount of data back in the count variable.

My test cases using a fd created by "int pipe(int pipefd[2]);" and passing data through that work fine with asio::async_read so I am thinking it could be a couple of options:

  • Some how the native descriptor I am passing isn't compatible with async_read in some way so it is failing silently. I have tried creating it with blocking on and off with no avail.
  • The io_service and the posix::stream_descriptor is some how not connected so the io_service never tries to run the read. Could this be due to me passing the io_service around by reference? (And within a couple of threads as well for that matter?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

聆听风音 2024-12-27 17:25:42

我发现了这个问题。

我在拥有对象的初始化函数中调用 io_service.stop() ,因为它可以重新初始化。然而,在调用停止后我没有调用 io_service.reset() ,并且 io_service 在停止后不会运行,直到调用重置为止。

RTFM 中的一课作为停止和重置都记录了这一点。

然而 boost::system::error_code 变量并没有反映这种状态,这有点令人沮丧,因为它可以让我省去一些麻烦。

I found the issue.

I was calling io_service.stop() in the initialization function of the owning object as it can be re-initialised. I wasn't calling io_service.reset() after the call to stop however and io_service won't run after a stop until reset has been called.

A lesson in RTFM as both stop and reset document this.

However the boost::system::error_code variable didn't reflect this state which is a bit frustrating as it would have saved me messing around.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文