What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?
Hi, My program needs a sync udp socket send / receiver so I use the deadline_timer as timeout for udp socket receive_from on Debian Jessie: boost::asio::deadline_timer deadline(io_service, boost::posix_time::seconds(2)); In checkDeadline function, when the timer expires, it calls socket.cancel, otherwise calls the deadline.async_wait(checkDeadline); again. Apparently when the program runs to socket.receive_from(), it is blocked and the timer is never called because both socket.receive_from and the timer in the same thread. I've been thinking to run the timer in another thread, but I checked Internet, there are comments said deadline_timer is not thread safe, please correct me if I am wrong here. It will be a simple solution for me if I can run timer on another thread. Anyone has other ideas to run the timer effectively? Appreciate your comments. Thank you.
2017-04-12 19:17 GMT+08:00 jupiter via Boost-users < boost-users@lists.boost.org>:
Hi,
My program needs a sync udp socket send / receiver so I use the deadline_timer as timeout for udp socket receive_from on Debian Jessie:
boost::asio::deadline_timer deadline(io_service, boost::posix_time::seconds(2));
In checkDeadline function, when the timer expires, it calls socket.cancel, otherwise calls the deadline.async_wait(checkDeadline); again.
Apparently when the program runs to socket.receive_from(), it is blocked and the timer is never called because both socket.receive_from and the timer in the same thread.
I've been thinking to run the timer in another thread, but I checked Internet, there are comments said deadline_timer is not thread safe, please correct me if I am wrong here. It will be a simple solution for me if I can run timer on another thread. Anyone has other ideas to run the timer effectively?
Unfortunately, asio timers are useless with those blocking calls, you have to use the async version (e.g. async_receive_from) and code in async fashion instead.
You are right, I did notice an example code given by http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/timeouts/bl... where the async_receive and timer are used. I left this out in my original post because I have lots of issues from that example, let me know if you'd like me to have a separate post, here are the problems: (1) That example can only work with an IP address in local machine, if I change to a remote machine IP address, it got an error of "Exception: bind: Cannot assign requested address'. (2) If my server is running at the same local machine with the same port number, it got an error of "Exception: bind: Address already in use". How can test that example? I need to add an async_send and I need to run it with a local server. Thank you. On Thu, Apr 13, 2017 at 1:46 AM, TONGARI J via Boost-users < boost-users@lists.boost.org> wrote:
2017-04-12 19:17 GMT+08:00 jupiter via Boost-users < boost-users@lists.boost.org>:
Hi,
My program needs a sync udp socket send / receiver so I use the deadline_timer as timeout for udp socket receive_from on Debian Jessie:
boost::asio::deadline_timer deadline(io_service, boost::posix_time::seconds(2));
In checkDeadline function, when the timer expires, it calls socket.cancel, otherwise calls the deadline.async_wait(checkDeadline); again.
Apparently when the program runs to socket.receive_from(), it is blocked and the timer is never called because both socket.receive_from and the timer in the same thread.
I've been thinking to run the timer in another thread, but I checked Internet, there are comments said deadline_timer is not thread safe, please correct me if I am wrong here. It will be a simple solution for me if I can run timer on another thread. Anyone has other ideas to run the timer effectively?
Unfortunately, asio timers are useless with those blocking calls, you have to use the async version (e.g. async_receive_from) and code in async fashion instead.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
2017-04-13 9:01 GMT+08:00 jupiter via Boost-users < boost-users@lists.boost.org>:
You are right, I did notice an example code given by http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/ example/timeouts/blocking_udp_client.cpp where the async_receive and timer are used. I left this out in my original post because I have lots of issues from that example, let me know if you'd like me to have a separate post, here are the problems:
(1) That example can only work with an IP address in local machine, if I change to a remote machine IP address, it got an error of "Exception: bind: Cannot assign requested address'.
(2) If my server is running at the same local machine with the same port number, it got an error of "Exception: bind: Address already in use".
How can test that example? I need to add an async_send and I need to run it with a local server.
Actually the example doesn't seem correct, it uses async_receive w/o connecting to a remote endpoint first, while the doc says: "The async_receive operation can only be used with a connected socket. Use the async_receive_from function to receive data on an unconnected datagram socket." Anyway, the listen_endpoint in the example is a local endpoint which is bind to the client, this may seem weird as it's actually a server in traditional sense.
2017-04-13 10:11 GMT+08:00 TONGARI J
2017-04-13 9:01 GMT+08:00 jupiter via Boost-users < boost-users@lists.boost.org>:
You are right, I did notice an example code given by http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/exa mple/timeouts/blocking_udp_client.cpp where the async_receive and timer are used. I left this out in my original post because I have lots of issues from that example, let me know if you'd like me to have a separate post, here are the problems:
(1) That example can only work with an IP address in local machine, if I change to a remote machine IP address, it got an error of "Exception: bind: Cannot assign requested address'.
(2) If my server is running at the same local machine with the same port number, it got an error of "Exception: bind: Address already in use".
How can test that example? I need to add an async_send and I need to run it with a local server.
Actually the example doesn't seem correct, it uses async_receive w/o connecting to a remote endpoint first, while the doc says:
"The async_receive operation can only be used with a connected socket. Use the async_receive_from function to receive data on an unconnected datagram socket."
Anyway, the listen_endpoint in the example is a local endpoint which is bind to the client, this may seem weird as it's actually a server in traditional sense.
BTW, here's the same example rewritten with co2 https://github.com/jamboree/co2+act https://github.com/jamboree/act: https://gist.github.com/jamboree/b0b8a81bb5d3acdca8b2b2557e9b7f1d ...if you're interested in what the code written in stackless coroutine would like.
On 04/13/2017 05:06 AM, TONGARI J via Boost-users wrote:
I am intrigued by your act::detail::move_wrapper and especially the "somewhat requires" comment. Does that mean that Asio checks for CopyConstructible, but does not actually copy the handler?
2017-04-13 19:00 GMT+08:00 Bjorn Reese via Boost-users < boost-users@lists.boost.org>:
On 04/13/2017 05:06 AM, TONGARI J via Boost-users wrote:
act https://github.com/jamboree/act:
I am intrigued by your act::detail::move_wrapper and especially the "somewhat requires" comment. Does that mean that Asio checks for CopyConstructible, but does not actually copy the handler?
Yes. I think the standalone ASIO has relaxed the restriction.
Thanks all responses, after searching from Internet, it seems many people have asked for udp socket sync receive timeout, the issue has been around for many years https://svn.boost.org/trac/boost/ticket/2832. Anyway, I am giving up sync approach and I am going to change my program to use async receive. Thank you all for your helpful comments. On Thu, Apr 13, 2017 at 11:26 PM, TONGARI J via Boost-users < boost-users@lists.boost.org> wrote:
2017-04-13 19:00 GMT+08:00 Bjorn Reese via Boost-users < boost-users@lists.boost.org>:
On 04/13/2017 05:06 AM, TONGARI J via Boost-users wrote:
act https://github.com/jamboree/act:
I am intrigued by your act::detail::move_wrapper and especially the "somewhat requires" comment. Does that mean that Asio checks for CopyConstructible, but does not actually copy the handler?
Yes. I think the standalone ASIO has relaxed the restriction.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 13/04/2017 13:01, jupiter via Boost-users wrote:
You are right, I did notice an example code given by http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/timeouts/bl... where the async_receive and timer are used. I left this out in my original post because I have lots of issues from that example, let me know if you'd like me to have a separate post, here are the problems:
(1) That example can only work with an IP address in local machine, if I change to a remote machine IP address, it got an error of "Exception: bind: Cannot assign requested address'.
Of course. You are specifying the address to listen at, which must be a local address. The only reason it allows an IP at all is for machines that have multiple adapters; you need to specify which adapter to listen on, or use ip::address_v4::any() to listen on all adapters.
(2) If my server is running at the same local machine with the same port number, it got an error of "Exception: bind: Address already in use".
How can test that example? I need to add an async_send and I need to run it with a local server.
The server accepts two separate port numbers. The first is the port for the TCP server itself, the second is the port for the UDP client. These must be different, and the latter must be the same as the port used when running the UDP client. You need to run the server, one or both of the two TCP clients, and the UDP client; the TCP client sends something to the server, which relays it to the UDP clients. Or at least that's what it looks like after spending 30 seconds reading the code and associated comments.
participants (4)
-
Bjorn Reese
-
Gavin Lambert
-
jupiter
-
TONGARI J