如何在等待时取消`boost :: asio :: read`操作

时间:2017-01-06 16:31:15

标签: c++ sockets boost-asio

我正在使用boost::asio将数据传输到&从客户端到服务器。我在客户端有一个读取器线程来读取客户端上的套接字上收到的数据。请注意,我在客户端使用boost::asio::read&服务器端boost::asio::write。 不使用async_readasync_write。一切都很好。

然而,当我关闭我的应用程序时,2次10次应用程序没有干净地拆卸或正常关闭。关闭时它会挂起问题如下:

在我的应用程序关闭期间调用析构函数时,将调用我的结束函数。以下是关闭功能的代码:

socket.cancel();
socket.close();
boost::system::error_code ec;
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);

问题是当boost::asio::read调用没有获得任何数据时,它不会返回。一直在等它。只要我可以取消它,这应该没问题。我正在尝试对其执行socket.cancel以在退出时取消所有读取操作。 但是,它似乎不起作用。我在一些论坛中读到socket.cancel仅取消async_read次操作。是这样吗 ? 当我的应用程序需要退出时,取消boost :: asio :: read`操作的方法是什么?

3 个答案:

答案 0 :(得分:3)

阻止IO的本质。

确实socket.cancel()(甚至io_service::stop())不适用于同步操作。

中断此操作的唯一方法是使用套接字级超时(但Asio不公开)或使用异步信号(例如,在终端中按Ctrl-C会向子进程发送SIGINT)。 / p>

如果您坚持在超时时间内运行单个操作,我之前创建了一个穷人的包装器:

答案 1 :(得分:0)

text

以上代码可帮助我立即关闭同步读取。
并同步读取,返回错误代码:boost :: asio :: error :: eof
我不知道为什么您的代码 IPAddress[] IpInHostAddress = Dns.GetHostAddresses("PCNAME"); strIpAddress = IpInHostAddress[0].ToString(); 无法正常工作。

也许您应该再试一次。

答案 2 :(得分:0)

该错误是由于在调用socket.close()之前调用了socket.shutdown()。如果在挂起的同步read()期间关闭套接字,则偶尔会出现该错误。确实是由于预期的底层asio套接字代码中存在数据争用。

尝试删除socket.close()呼叫。假设您的套接字包装在某种shared_ptr中,则可以让套接字析构函数关闭基础套接字。

您仍然需要在用例中显式调用socket.cancel()socket.shutdown(),以取消未完成的操作。