What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
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.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
2017-04-12 19:17 GMT+08:00 jupiter via Boost-users <[hidden email]>:
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
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
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.



On Thu, Apr 13, 2017 at 1:46 AM, TONGARI J via Boost-users <[hidden email]> wrote:
2017-04-12 19:17 GMT+08:00 jupiter via Boost-users <[hidden email]>:
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
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
2017-04-13 9:01 GMT+08:00 jupiter via Boost-users <[hidden email]>:
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.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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.


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
2017-04-13 10:11 GMT+08:00 TONGARI J <[hidden email]>:
2017-04-13 9:01 GMT+08:00 jupiter via Boost-users <[hidden email]>:
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.

BTW, here's the same example rewritten with co2+act:

...if you're interested in what the code written in stackless coroutine would like.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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?

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
2017-04-13 19:00 GMT+08:00 Bjorn Reese via Boost-users <[hidden email]>:
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
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the effective way to use boost::asio::deadline_timer for udp socket receive_from?

Boost - Users mailing list
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 <[hidden email]> wrote:
2017-04-13 19:00 GMT+08:00 Bjorn Reese via Boost-users <[hidden email]>:
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
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Loading...