asio UDP message packet loss even on localhost?

Hi, I'm having a very basic issue: when sending a large number of UDP messages in short succession via boost::asio, even to localhost, after a few hundred messages, there seems to be a serious loss. please see a sample code here: http://pastebin.com/Bq0DnkeG the output I get is the following: $ ./async_asio 0 1 2 3 ... 939 940 941 942 943 944 958 983 1013 1049 1093 1151 1234 1363 1576 1943 b sent 2000 messages a received 955 messages so, basically while 2000 messages were sent over, only up to 944 were received so that all of them are, an then there are only sporadic messages received afterwards - a total of 955. while I understand UDP is not guaranteed to be sent over, such a level of unreliability to the localhost interface seems to be quite troublesome.. what am I doing wrong? Akos

I'm having a very basic issue: when sending a large number of UDP messages in short succession via boost::asio, even to localhost, after a few hundred messages, there seems to be a serious loss.
please see a sample code here: http://pastebin.com/Bq0DnkeG
I run your code (Win7, MSVC10, boost 1.44), and I can't reproduce the issue you describe, the output is always: b sent 2000 messages a received 2000 messages Anyway, if I read your code correctly, you assume that all these messages should be sent/received within 1 second, don't you? What if you increase this value?

On 22/10/10 14:42, Igor R wrote:
I run your code (Win7, MSVC10, boost 1.44), and I can't reproduce the issue you describe, the output is always: b sent 2000 messages a received 2000 messages
interesting. I'm using boost 1.40 on a Linux box (Ubuntu 10.04 64bit), and we also tried with boost 1.40 on a Windows box, with the same results. maybe I should try with a more recent boost version
Anyway, if I read your code correctly, you assume that all these messages should be sent/received within 1 second, don't you? What if you increase this value?
this is already the result of increasing this sleep period. the results are the same for 100ms already, raising to 1000ms didn't make a difference, doubt longer values would..

Igor R wrote:
I'm having a very basic issue: when sending a large number of UDP messages in short succession via boost::asio, even to localhost, after a few hundred messages, there seems to be a serious loss.
On XP I have seen UDP loss localhost with plain sockets when a machine is under load. I assume that MS literally take the unreliable part of UDP and discard the packets. Remember the localhost IP stack on windows is not the same the more real IP stack on Linux/Unix boxes, there are performance ;) enhancements
please see a sample code here: http://pastebin.com/Bq0DnkeG
I run your code (Win7, MSVC10, boost 1.44), and I can't reproduce the issue you describe, the output is always: b sent 2000 messages a received 2000 messages
Anyway, if I read your code correctly, you assume that all these messages should be sent/received within 1 second, don't you? What if you increase this value? _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Igor,
I run your code (Win7, MSVC10, boost 1.44), and I can't reproduce the issue you describe, the output is always: b sent 2000 messages a received 2000 messages
I gave it a shot using boost 1.44, freshly downloaded & compiled, but I get the same results. the pattern is the same: up until a certain number of packets, everything is received. but there's an obvious breaking point, after which only a few packets will be received, maybe less than five. one way I could make it send / receive all the packets was to add a millisecond of sleep after each send: for (unsigned int i = 0; i < 2000; ++i) { std::stringstream sstr; sstr << i; b.send(endp_a, sstr.str()); boost::this_thread::yield(); boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } this indicates the problem to be a threading issue. but wouldn't a yield() be enough? putting in a 1ms sleep every 100 sends also works most of the time: for (unsigned int i = 0; i < 2000; ++i) { std::stringstream sstr; sstr << i; b.send(endp_a, sstr.str()); if (i % 100 == 0) { boost::this_thread::yield(); boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } } but putting the 1ms sleep in every 1000 sends will break things again. the results seem to be the same with boost 1.40 and 1.44.
Anyway, if I read your code correctly, you assume that all these messages should be sent/received within 1 second, don't you? What if you increase this value?
giving 1 seconds or 5 seconds gives the same result. Akos

Hi, void handle_send_to(const boost::system::error_code& error, size_t /*bytes_sent*/) { if (error) { std::cout << "send error!" << std::endl; } ++messages_sent_; socket_.async_receive_from( boost::asio::buffer(data_, max_length), sender_endpoint_, boost::bind(&server::handle_receive_from, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } 2000 times "async_receive_from" in sending server it's not so good, i think. Without it all work fine.

Yuri,
void handle_send_to(const boost::system::error_code& error, size_t /*bytes_sent*/) { if (error) { std::cout << "send error!" << std::endl; }
++messages_sent_;
socket_.async_receive_from( boost::asio::buffer(data_, max_length), sender_endpoint_, boost::bind(&server::handle_receive_from, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }
2000 times "async_receive_from" in sending server it's not so good, i think. Without it all work fine.
good point. as just stated in the earlier mail, this code was a leftover from a sample I started out with. now having removed it seems to have solved my problem. thanks, Akos

Akos wrote:
I'm having a very basic issue: when sending a large number of UDP messages in short succession via boost::asio, even to localhost, after a few hundred messages, there seems to be a serious loss.
please see a sample code here: http://pastebin.com/Bq0DnkeG
I am no ASIO expert, but a few things came to mind: 1) As far as I know, it is not safe to do a async_send operation on a socket before the previous async_send operation has completed. I have seen this mentioned somewhere in the documentation, but can't find the place now. 2) Line 56: The logic in handle_send_to seems flawed. It issues a async_receive_from()? I would expect it to either send another UDP packet or just check the error code from the original send operation. 3) Line 116: The lifetime of the buffer passed to send() may end before the async operation completes. This will likely not cause the issues seen here, but worth mentioning. Have you tried - just for debugging - changing the send() operation to be synchronous? Have a nice weekend, Martin Dyring-Andersen

Martin, thanks for your feedback.
I am no ASIO expert, but a few things came to mind:
1) As far as I know, it is not safe to do a async_send operation on a socket before the previous async_send operation has completed. I have seen this mentioned somewhere in the documentation, but can't find the place now.
it might be. then again, all send events seem to complete find, as the send callback is called the proper number of times.
2) Line 56: The logic in handle_send_to seems flawed. It issues a async_receive_from()? I would expect it to either send another UDP packet or just check the error code from the original send operation.
this is a leftover from the boost asio sample code I copied it over from, see here: http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/example/echo/async_... removing it actually solves my issue. wow - I wouldn't have thought :) now I'm hitting the following barriers: b sent 200000 messages a received 199597 messages b sent 2000000 messages a received 1990728 messages these both seem to be over 99% fidelity, which is, well, sort of OK :)
3) Line 116: The lifetime of the buffer passed to send() may end before the async operation completes. This will likely not cause the issues seen here, but worth mentioning.
actually an asio::buffer object is created in send(), which copies the contents over. this is the same pattern as used in the same sample code quoted above.
Have you tried - just for debugging - changing the send() operation to be synchronous?
actually haven't. Akos

On 10/22/2010 7:53 AM, Ákos Maróy wrote:
actually an asio::buffer object is created in send(), which copies the contents over. this is the same pattern as used in the same sample code quoted above.
This is a common error. The asio::buffer simply wraps the memory and provides a starting location and size. You still must manage the memory. http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/buffer.ht... michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

On 22/10/10 17:08, Michael Caisse wrote:
On 10/22/2010 7:53 AM, Ákos Maróy wrote:
actually an asio::buffer object is created in send(), which copies the contents over. this is the same pattern as used in the same sample code quoted above.
This is a common error. The asio::buffer simply wraps the memory and provides a starting location and size. You still must manage the memory.
http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/buffer.ht...
thanks for pointing this out. it would be nice to get rid of this wrong pattern in the 'official' example code too :)

On 10/22/2010 8:12 AM, Ákos Maróy wrote:
actually an asio::buffer object is created in send(), which copies the contents over. this is the same pattern as used in the same sample code quoted above. This is a common error. The asio::buffer simply wraps the memory and
On 10/22/2010 7:53 AM, Ákos Maróy wrote: provides a starting location and size. You still must manage the memory.
http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/reference/buffer.ht...
On 22/10/10 17:08, Michael Caisse wrote: thanks for pointing this out. it would be nice to get rid of this wrong pattern in the 'official' example code too :)
The code examples do this correctly. It uses a private data member in the class named data_. The pattern uses bind and shared_from_this in the handlers to ensure lifetime. That is the correct way. You may find my boostcon10 slides useful. Ownership of memory buffers is part of the proactor model. http://www.objectmodelingdesigns.com/boostcon10/ http://www.blip.tv/file/4171562/ michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

Michael,
The code examples do this correctly. It uses a private data member in the class named data_. The pattern uses bind and shared_from_this in the handlers to ensure lifetime. That is the correct way.
You may find my boostcon10 slides useful. Ownership of memory buffers is part of the proactor model.
http://www.objectmodelingdesigns.com/boostcon10/ http://www.blip.tv/file/4171562/
thank you - I'll take a look.. Akos

On 2010-10-22 10:37, Ákos Maróy wrote:
Hi,
I'm having a very basic issue: when sending a large number of UDP messages in short succession via boost::asio, even to localhost, after a few hundred messages, there seems to be a serious loss.
please see a sample code here: http://pastebin.com/Bq0DnkeG
Not sure if it's related to your problem, but AFAICT you are not managing your resources in a correct way. Everything passed to an 'async_' function should outlive the full async operation. E.g., in your 'send' function you use a RValue string -- this will most probably not outlive the async_send_to operation. Perhaps related to your problem, is that you are counting the number of "received_from" callbacks, not the number of received messages. Couldn't it be that you receive multiple messages in one callback? HtH, Rutger

Rutger,
Not sure if it's related to your problem, but AFAICT you are not managing your resources in a correct way. Everything passed to an 'async_' function should outlive the full async operation. E.g., in your 'send' function you use a RValue string -- this will most probably not outlive the async_send_to operation.
thanks for the observation. as stated in an earlier e-mail, this code comes from this sample: http://www.boost.org/doc/libs/1_44_0/doc/html/boost_asio/example/echo/async_...
Perhaps related to your problem, is that you are counting the number of "received_from" callbacks, not the number of received messages. Couldn't it be that you receive multiple messages in one callback?
my presumption would be that this is called each time a message is received. also, when saving & printing out these messages, it is clear that messages are received exactly as they are sent. Akos
participants (7)
-
Igor R
-
Martin Dyring-Andersen
-
Michael Caisse
-
Reynolds, John
-
Rutger ter Borg
-
Yuri T.
-
Ákos Maróy