[Boost-users] Multiple async operations on a socket

329 views
Skip to first unread message

Kyle Tarplee

unread,
Sep 16, 2009, 10:41:43 AM9/16/09
to boost...@lists.boost.org
I have a rather simple question that I can't find in the boost::asio
documentation.

I have a boost::asio::ip::tcp::socket that I want to write to. Can I
have multiple outstanding async_write() requests for a single socket?
Are the writes performed in the order in which they are submitted? Or
is this undefined behavior?

How about multiple async_read() requests on the same socket?

I know that I need to write to the socket from at most one thread but
that doesn't preclude me from not waiting until the first one is done
to put on the second async write or read.

The reason I ask is because there seems to be two ways to write data
to a socket.
1) The "fire and forget" approach (no queue, simply call async_write()
when you want to write and ignore the completion
handler callback)
2) Push on a queue when you want to write something. Pop from the
queue when the preceeding
async_write() operation completed. Thus at most one
async_write()
operation is
associated with the socket at any point in time.

Thanks in advance,
Kyle
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Roman Shmelev

unread,
Sep 16, 2009, 3:11:19 PM9/16/09
to boost...@lists.boost.org
> I have a boost::asio::ip::tcp::socket that I want to write to.   Can I
> have multiple outstanding async_write() requests for a single socket?
> Are the writes performed in the order in which they are submitted?  Or
> is this undefined behavior?
>
> How about multiple async_read() requests on the same socket?

Do not do multiple. Make your own simple queue for each connection and be happy.
I'm acquainted with this problem and got quite bad behavior when using
multiple async_write's at once.

Of course, you still can run async_read and async_write together for
one connection.

Of course, you still can run multiple async_read's, async_write's,
when you have multiple connections.

Hope this helps.
BTW, you can find in boost archives two discussions on similar topic.

Igor R

unread,
Sep 16, 2009, 3:39:05 PM9/16/09
to boost...@lists.boost.org
> I have a boost::asio::ip::tcp::socket that I want to write to.   Can I have multiple outstanding async_write() requests for a single socket?

asio::async_write() is a convenience function that calls
socket::async_write_some() multiple times - until all the data is
sent. This means that if you issue multiple asio::async_write's, the
data will be interleaved in most cases.
As for multiple async_write_some(), it will probably work on some
platforms... But note that async_write_some doesn't promise to send
all your data. So you can't "fire and forget" anyway.

Matheus Araújo Aguiar

unread,
Sep 16, 2009, 4:40:20 PM9/16/09
to boost...@lists.boost.org
I had the same doubt, and asked the same think some weeks ago. Here's what helped me figuring out what happens:
 - http://archives.free.net.ph/message/20090821.085221.7ccd0f8a.pt-BR.html
 - http://www.jetbyte.com/portfolio-showarticle.asp?articleId=44&catId=1&subcatId=2

Regards,
--
Matheus Araújo Aguiar
Computer Scientist
mathe...@gmail.com

Kyle Tarplee

unread,
Sep 17, 2009, 9:27:59 AM9/17/09
to boost...@lists.boost.org
So it seems you can not have multiple outstanding async_read_some or async_write_some.  This makes since.

Now the thing that doesn't make since is that since a user could easily make such an error and the problem would be hard to track down (for instance it hasn't caused me a problem yet, just wasn't getting the warm fuzzy feeling about what I was doing) why does ASIO's socket not throw an error or behave more like the deadline_timer when one tries to create multiple async_ operations.  The deadline_timer kindly cancels the async_wait() when you call expires_fron_now().  It seems like the socket could cancel the previous read/write by calling it's callback with an error like operation_aborted.

Kyle

<ATT00001..txt>

Matheus Araújo Aguiar

unread,
Sep 17, 2009, 10:02:33 AM9/17/09
to boost...@lists.boost.org
On Thu, Sep 17, 2009 at 10:27 AM, Kyle Tarplee <Kyle.T...@numerica.us> wrote:
So it seems you can not have multiple outstanding async_read_some or async_write_some.  This makes since.

You might have multiple outstanding async requests. But in that case, you must write code to assure consistence. For async_read, the completion handlers may be called out of order, so you need to keep track about the order of the requests (you could, for example, give a sequence number for each async_read, and pass that number to the callback function). On the other hand, for async_write, since it is divided in many async_write_some, you must wait one operation complete before requesting another one. This avoids your data being interleaved.
Read the links I posted in earlier message for further information.

Kindly,
 

Igor R

unread,
Sep 17, 2009, 10:08:36 AM9/17/09
to boost...@lists.boost.org
>For async_read, the completion handlers may be called out of order, so you need to keep track about the
> order of the requests (you could, for example, give a sequence number for each async_read, and pass that number to the callback function). On the other hand, for async_write, since it is divided in many async_write_some,

async_read() also performs multiple socket::async_read_some()

Reply all
Reply to author
Forward
0 new messages