
Hello list, Could someone please shed some light on this subject. It seems that me read handler keeps on being called even when there has been no data transferred... Here is the accept handler that starts off the read handler (All methods are part of the same class, namely 'client'): /* Accept Handler */ void handle_accept( const boost::system::error_code& error ) { client* c; switch(error.value()) { case boost::system::posix_error::success: { c = new client(); socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ); break; } case boost::system::posix_error::interrupted: case boost::system::posix_error::connection_aborted: { c = this; break; } default: { throw error; } } acceptor.async_accept( c->socket, boost::bind( &client::handle_accept, c, boost::asio::placeholders::error ) ); }; And here is the read handler.... /* Read Handler */ void handle_read( const boost::system::error_code& error, std::size_t bytes_transferred ) { switch(error.value()) { case boost::system::posix_error::success: { if(bytes_transferred > 0) { std::copy( buffer.begin(), buffer.end(), std::back_insert_iteratorstd::string(data) ); break; } } case boost::system::posix_error::interrupted: { socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ); return; } default: { throw error; } } //TODO: parse contents.. }; Using epoll interface, as I am running Ubuntu Jaunty. Calling io_service.run() from the main thread. Thank you, Etienne Pretorius.

Hi Etienne - Etienne Philip Pretorius wrote:
Hello list,
Could someone please shed some light on this subject. It seems that me read handler keeps on being called even when there has been no data transferred...
switch(error.value()) { case boost::system::posix_error::success: { c = new client();
socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) );
Try changing this to use socket.async_read_some instead of async_receive. Regards - michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

Michael Caisse wrote:
Hi Etienne -
Etienne Philip Pretorius wrote:
Hello list,
Could someone please shed some light on this subject. It seems that me read handler keeps on being called even when there has been no data transferred...
switch(error.value()) { case boost::system::posix_error::success: { c = new client();
socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) );
Try changing this to use socket.async_read_some instead of async_receive.
Regards - michael
:D, just tried it - still no luck. I am invesigating if I am calling the buffer correctly. It seems that after the call to async_receive/async_read_some that there is still data pending for me to read... IE I never seem to get the data placed inside the std::vector correctly. Kind Regards, Etienne

On Tue, Jun 30, 2009 at 1:46 PM, Etienne Philip
Pretorius
Michael Caisse wrote:
Hi Etienne -
Etienne Philip Pretorius wrote:
Hello list,
Could someone please shed some light on this subject. It seems that me read handler keeps on being called even when there has been no data transferred...
switch(error.value()) { case boost::system::posix_error::success: { c = new client();
socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) );
Try changing this to use socket.async_read_some instead of async_receive.
Regards - michael
:D, just tried it - still no luck. I am invesigating if I am calling the buffer correctly. It seems that after the call to async_receive/async_read_some that there is still data pending for me to read... IE I never seem to get the data placed inside the std::vector correctly.
Are you saying that the handler is constantly getting called with bytes_transferred = 0? What is contained inside your buffer object? If your buffer has a size of 0, then this seems like it would cause the problem. Also, do you mean that for a single invocation of async_receive(), the handler is getting called multiple times? Or that for each call to async_receive, the handler gets called once with bytes_transferred=0? Is there an error code?

Zachary Turner wrote:
On Tue, Jun 30, 2009 at 1:46 PM, Etienne Philip Pretorius
wrote: Michael Caisse wrote:
Hi Etienne -
Etienne Philip Pretorius wrote:
Hello list,
Could someone please shed some light on this subject. It seems that me read handler keeps on being called even when there has been no data transferred...
switch(error.value()) { case boost::system::posix_error::success: { c = new client();
socket.async_receive( boost::asio::buffer( buffer ),boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) );
Try changing this to use socket.async_read_some instead of async_receive.
Regards - michael
:D, just tried it - still no luck. I am invesigating if I am calling the buffer correctly. It seems that after the call to async_receive/async_read_some that there is still data pending for me to read... IE I never seem to get the data placed inside the std::vector correctly.
Are you saying that the handler is constantly getting called with bytes_transferred = 0?
yes
What is contained inside your buffer object? If your buffer has a size of 0, then this seems like it would cause the problem.
yip, it has a size of 0. I hoped that the async receive would just increase the size of the vector as it puts the contents into it, but that is not happening.
Also, do you mean that for a single invocation of async_receive(), the handler is getting called multiple times? Or that for each call to async_receive, the handler gets called once with bytes_transferred=0? Is there an error code? The handler gets called once per invocation with bytes_transferred = 0 and error.value() = 0.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users T

On Tue, Jun 30, 2009 at 2:24 PM, Etienne Philip Pretorius
wrote: Zachary Turner wrote: What is contained inside your buffer object? If your buffer has a size of 0, then this seems like it would cause the problem.
yip, it has a size of 0. I hoped that the async receive would just increase the size of the vector as it puts the contents into it, but that is not happening.
I'm 99% sure this is your problem. I haven't used asio with sockets, but I have used it with other types of input sources. It doesn't know how much data to read unless you tell it. The way you tell it is by giving it a buffer whose size is how much data you want to read. That means that allocation / deletion of the buffer is also your responsibility. boost::asio::const_buffer and boost::asio::mutable_buffer have no ownership over the memory contained in these buffers. It seems like this makes the library a little less intuitive at first, I struggled for quite a while with buffer management in my own project, but in the end it is this way to help you. Otherwise there would be excessive copying and allocation. mutable_buffer and const_buffer are just very thin wrappers over a chunk of memory. So you have to allocate a buffer up front that contains enough memory for whatever it is you're trying to read. Then you pass that to async_receive and it should work. const size_t expected = 4096; unsigned char* buf = new unsigned char[expected]; boost::asio::mutable_buffer(buf, expected); socket.async_receive( boost::asio::buffer(buffer), boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred Now in your handler you will either need to free this buffer, release it to some cache, or whatever else you want to do with it.

Zachary Turner wrote:
On Tue, Jun 30, 2009 at 2:24 PM, Etienne Philip Pretorius
wrote: Zachary Turner wrote: What is contained inside your buffer object? If your buffer has a size of 0, then this seems like it would cause the problem.
yip, it has a size of 0. I hoped that the async receive would just increase the size of the vector as it puts the contents into it, but that is not happening.
I'm 99% sure this is your problem. I haven't used asio with sockets, but I have used it with other types of input sources. It doesn't know how much data to read unless you tell it. The way you tell it is by giving it a buffer whose size is how much data you want to read. That means that allocation / deletion of the buffer is also your responsibility.
boost::asio::const_buffer and boost::asio::mutable_buffer have no ownership over the memory contained in these buffers. It seems like this makes the library a little less intuitive at first, I struggled for quite a while with buffer management in my own project, but in the end it is this way to help you. Otherwise there would be excessive copying and allocation. mutable_buffer and const_buffer are just very thin wrappers over a chunk of memory. So you have to allocate a buffer up front that contains enough memory for whatever it is you're trying to read. Then you pass that to async_receive and it should work.
const size_t expected = 4096; unsigned char* buf = new unsigned char[expected]; boost::asio::mutable_buffer(buf, expected);
socket.async_receive( boost::asio::buffer(buffer), boost::bind( &client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
Now in your handler you will either need to free this buffer, release it to some cache, or whatever else you want to do with it. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users Not at my machine right now, but I am quite certain that you are correct. Thank you for your help, much appreciated.
Etienne

What is contained inside your buffer object? If your buffer has a size of 0, then this seems like it would cause the problem.
yip, it has a size of 0. I hoped that the async receive would just increase the size of the vector as it puts the contents into it, but that is not happening.
The function you use reads an amount of data that is less or equal than your buffer size. I.e. zero. If you want to get your buffer expanding automatically, you might be interested in this function (in conjunction with asio::streambuf) : http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/reference/async_rea...
participants (4)
-
Etienne Philip Pretorius
-
Igor R
-
Michael Caisse
-
Zachary Turner