[Boost-users] What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

1,153 views
Skip to first unread message

jupiter via Boost-users

unread,
Apr 12, 2017, 7:18:41 AM4/12/17
to boost...@lists.boost.org, jupiter
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.

TONGARI J via Boost-users

unread,
Apr 12, 2017, 11:47:02 AM4/12/17
to boost...@lists.boost.org, TONGARI J
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.

jupiter via Boost-users

unread,
Apr 12, 2017, 9:02:24 PM4/12/17
to boost...@lists.boost.org, jupiter
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.

Thank you.



_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

TONGARI J via Boost-users

unread,
Apr 12, 2017, 10:12:03 PM4/12/17
to boost...@lists.boost.org, TONGARI J
2017-04-13 9:01 GMT+08:00 jupiter via Boost-users <boost...@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.

Gavin Lambert via Boost-users

unread,
Apr 12, 2017, 10:43:19 PM4/12/17
to boost...@lists.boost.org, Gavin Lambert
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/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'.

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.

TONGARI J via Boost-users

unread,
Apr 12, 2017, 11:06:24 PM4/12/17
to boost...@lists.boost.org, TONGARI J
...if you're interested in what the code written in stackless coroutine would like.

Bjorn Reese via Boost-users

unread,
Apr 13, 2017, 7:02:29 AM4/13/17
to boost...@lists.boost.org, Bjorn Reese
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?

TONGARI J via Boost-users

unread,
Apr 13, 2017, 9:26:15 AM4/13/17
to boost...@lists.boost.org, TONGARI J
2017-04-13 19:00 GMT+08:00 Bjorn Reese via Boost-users <boost...@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.

jupiter via Boost-users

unread,
Apr 14, 2017, 4:42:13 AM4/14/17
to boost...@lists.boost.org, jupiter
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.

Reply all
Reply to author
Forward
0 new messages