gpt4 book ai didi

c++ - boost::asio 取消或关闭在 async_handle 上不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:04:53 25 4
gpt4 key购买 nike

boost::asio::ip::udp:socket 不能 cancel() async_handle,也不能 close()。

这是测试程序:

{
boost::asio::io_context io_core;
boost::asio::ip::udp::socket udp_socket1(io_core, udp::v4());
char buff[200];
boost::asio::ip::udp::endpoint endpoint1(boost::asio::ip::address::from_string("127.0.0.1"), 9999);

cout << udp_socket1.is_open() << endl;
udp_socket1.async_send_to(boost::asio::buffer(buff, 200), endpoint1, [&udp_socket1](const boost::system::error_code& ec, size_t wlen) {
cout << udp_socket1.is_open() << endl;
//assert(0);
});
cout << udp_socket1.is_open() << endl;
udp_socket1.close();
udp_socket1.async_send_to(boost::asio::buffer(buff, 200), endpoint1, [&udp_socket1](const boost::system::error_code& ec, size_t wlen) {
cout << udp_socket1.is_open() << endl;
//assert(0);
});
cout << udp_socket1.is_open() << endl;

udp_socket1.close();
io_core.run();
system("pause");
}

根据 documentation 定义的 boost 1.67.0、WIN10、vs2017 BOOST_ASIO_DISABLE_IOCP 和 BOOST_ASIO_CANCELIO

我没听懂吗?

如果我是正确的,如何解决这个问题?

最佳答案

异步操作不会立即完成。您的代码看起来像您期望的那样。

将您的代码简化为:

Live On Coliru

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

using boost::asio::ip::udp;

int main() {
std::cout << std::boolalpha;

boost::asio::io_context io;
boost::asio::ip::udp::socket s {io, udp::v4()};
boost::asio::ip::udp::endpoint const ep {{}, 9999};

auto trace = [&s](char const* caption) { std::cout << caption << s.is_open() << std::endl; };
auto handler = [=](boost::system::error_code, size_t) { trace("handler: "); };

trace("main #1: ");

char buff[200] = {};
s.async_send_to(boost::asio::buffer(buff), ep, handler);

trace("main #2: ");
s.close();

s.async_send_to(boost::asio::buffer(buff), ep, handler);

trace("main #3: ");
s.close();

io.run();
}

处理程序仅在 io.run() 之后运行是有道理的;很明显,套接字只有在第一次关闭之前才会“打开”:

main #1: true
main #2: true
main #3: false
handler: false
handler: false

这完全符合预期。所以,要么你应该处理错误:

Live On Coliru

auto trace = [&s](char const* caption) { std::cout << caption << (s.is_open()?"open":"closed") << std::endl; };
auto handler = [=](boost::system::error_code ec, size_t) {
trace(("handler(" + ec.message() + "): ").c_str());
};

改为打印:

main #1: open
main #2: open
main #3: closed
handler(Success): closed
handler(Bad file descriptor): closed

Note that perhaps surprisingly, the first send operation still succeeded. Contrary to what I expected this indicates that the send is actually initiated right at the async_send_to call, but the completion is delayed until after io.run() (the socket is still shown to be already closed).

也许您根本不需要异步操作:

Live On Coliru

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

using boost::asio::ip::udp;

int main() {
std::cout << std::boolalpha;

boost::asio::io_context io;
boost::asio::ip::udp::socket s {io, udp::v4()};
boost::asio::ip::udp::endpoint const ep {{}, 9999};

auto trace = [&s](char const* caption) { std::cout << caption << s.is_open() << std::endl; };

trace("main #1: ");

char buff[200] = {};
try {
/*size_t wlen =*/ s.send_to(boost::asio::buffer(buff), ep);
trace("sent #1: ");
} catch(boost::system::system_error const& e) {
std::cout << "Send #1 failed: " << e.code().message() << std::endl;
}

trace("main #2: ");
s.close();

try {
/*size_t wlen =*/ s.send_to(boost::asio::buffer(buff), ep);
trace("sent #2: ");
} catch(boost::system::system_error const& e) {
std::cout << "Send #2 failed: " << e.code().message() << std::endl;
}

trace("main #3: ");
s.close();

io.run();
}

打印

main #1: true
sent #1: true
main #2: true
Send #2 failed: Bad file descriptor
main #3: false

关于c++ - boost::asio 取消或关闭在 async_handle 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52290390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com