Boost ASIO Buffering Not Working
I'm writing a networking application that uses ASIO/UDP to send and receive between a single remote/locale endpoint pair. I had used udp::socket::receive to receive data and everything in my code worked logically, but I was losing an enormous number of packets. What I discovered was that any packet received while not blocked on the receive function was lost - it wasn't buffering. This was particularly odd because I had set the receive buffer to 2MB using the following command:
sock_udp.connect( remote_endpoint );
sock_udp.set_option( boost::asio::socket_base::receive_buffer_size(2*1024*1024) );
This and the fact that if I sent only two packets of about 100 bytes each I would still lose the second one if I spent any time processing the first.
I figured that this was perhaps a flaw with udp::socket::receive, so I re-wrote my networking code to use udp::socket::async_receive
but I still have the same problem. That is, once my handler is called I drop any packets until I call async_receive again.
Am I fundamentally misunderstanding something? Is there a different approach I should be using for boost to buffer incoming packets?
If it helps, I've verified that this happens both in OS X in XCode using their custom gcc4.2 build, as well as Ubuntu 10.10 using gcc4.5. I have no yet been able to try it in Windows.开发者_运维知识库
The general idea here is that your program should spend the vast majority of it's time waiting on the socket to deliver something, either blocked in the UDP receive or waiting in the io_service for notification that the socket has asynchronously received something. The socket implicitly has a small buffer in the OS for receiving packets, there's no way to avoid it. So the problem is more likely in how your program is behaving.
- Is your thread anywhere but within the ASIO io_service? If so you can easily overflow any underlying socket buffer.
- Can you prove that, on average, the time spent between blocking calls is less than the time between packets being sent?
- You do have to call async_receive again after you receive data from the socket. For example you can issue another async_receive from within your receive handler.
精彩评论