boost::asio cancel or close doesn't work on async_handle
boost::asio cancel or close doesn't work on async_handle
boost::asio::ip::udp:socket can not cancel() the async_handle, nor close().
This is the test program:
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");
with boost 1.67.0, WIN10, vs2017 BOOST_ASIO_DISABLE_IOCP and BOOST_ASIO_CANCELIO defined according to the documentation
Did i fail to get the point?
If i am correct , how to fix this problem ?
1 Answer
1
Asynchronous operations do not complete immediately. Your code looks like you expect them to.
Simplifying your code to:
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();
It makes sense that the handler only run AFTER io.run(); And obviously the socket is only "open" until it got first closed:
io.run()
main #1: true
main #2: true
main #3: false
handler: false
handler: false
This is exactly expected. So, either you should handle errors:
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());
;
Printing instead:
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).
async_send_to
io.run()
And maybe you did not want async operations at all:
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();
Prints
main #1: true
sent #1: true
main #2: true
Send #2 failed: Bad file descriptor
main #3: false
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.