Message: 2
Date: Wed, 6 Feb 2008 23:43:09 -0000
From: "Roger Austin" <Roger@wallingfordsoftware.com>
Subject: Re: [asio-users] asio::async_write & WriteHander
To: <asio-users@lists.sourceforge.net>
Message-ID:
<0CEE50132F7DB142AA8632D6FB1BE982E7E462@bob.internal.wallingfordsoftware.co.uk>
Content-Type: text/plain; charset="us-ascii"
If there is ever an asio FAQ, the correct use of async_write will be at
the top of the list
Cliff is correct in what he says but the key clause is "when the first
async_write completes". If you start your second async_write before the
first has completed, you risk interleaving the data. Thus if you want to
write code like:
DoAsyncWrite("Message 1");
DoAsyncWrite("Message 2");
Then your implementation of DoAsyncWrite (which will call async_write
internally) must check if there is already an async_write pending and,
if so, put the message somewhere (i.e. in a queue), ready to be sent
when the pending async_write has completed. The asio chat example does
this.
This is not a limitation of asio as such. The underlying socket
functions (send or equivalent) make no guarantee that the entire message
can be transferred to the TCP stream in a single asynchronous operation
- the write handler will be told how many bytes were actually
transferred and the application is responsible for issuing a new call to
send the remaining bytes. The asio async_write function does this for
you via one or more calls to async_write_some, but in doing so it tends
to hide the fact that the second and later calls to async_write_some
(needed to complete sending the first message) may happen later in the
thread than the first call to async_write_some for the second message.
From: asio-users-bounces@lists.sourceforge.net
[mailto:asio-users-bounces@lists.sourceforge.net] On Behalf Of X Wang
Sent: Thursday, 7 February 2008 9:37 AM
To: asio-users@lists.sourceforge.net
Subject: Re: [asio-users] asio::async_write & WriteHander
"Green, Cliff" <cliff.green@boeing.com> wrote:
> Sender sends out 2 messages back to back (on the same end-to-end
socket
> connection), message 1 is 10 MB, message 2 is 10 bytes, with no
receiver
> ACK in between.
Assuming the two messages are generated in order (e.g. in a single
thread), there is not an issue - one async_write of 10 MB, followed by
an async_write of 10 bytes (when the first async_write completes). Since
the actual "buffer" passed to Asio async_write does not copy the 10 MB /
10 b, you will need to manage the lifetime of the two original message
buffers. If the "message generation" is completely independent of the
thread invoking the async_writes, you need to manage the coordination
(this could be a queue, as previously mentioned, or some other form of
coordination).
You will be guaranteed that the data gets to the receiver in the same
order - 10 MB followed by 10 b (however, the receiver will need to take
responsibility for the message delimiter handling).
Am I missing something?
(Asio experts, please correct any of my mistakes on the Asio aspects.)
Much of this explanation is not dependent on async concepts and designs
- it would need to be similar whether your app is blocking, non-blocking
(polling), non-blocking (reactive), multi-threaded, etc.
Cliff
------------------------------------------------------------------------
-
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
asio-users mailing list
asio-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/asio-users
Yeah, you are right. What I said about TCP did not make much sense...
need some coffee :)