[Interest] TCP ACK with QDataStream -- OR: disconnect race condition detection

Thiago Macieira thiago.macieira at intel.com
Mon Sep 10 12:19:04 CEST 2012


On segunda-feira, 10 de setembro de 2012 12.02.38, Till Oliver Knoll wrote:
> Am 09.09.2012 um 21:17 schrieb Justin Karneges <justin at affinix.com>:
> > You're correct in that it is reliable under the hood. The problem is
> > really
> > just that most TCP APIs don't expose to the app what has been
> > acknowledged.
> 
> Not entirely true: on a "socket level" you get the number of bytes which
> have been ACK'ed ("successfully read") by the counterparty's Transport
> (TCP) layer - that is, they are now stored in the counterparty's
> (receiver's) read buffer, ready to be picked up by the Application layer
> (whether the counterparty's Application layer will eventually do so we
> don't know!).
> 
> Qt /does/ provide you with this info! That's what the signal
> QIODevice::bytesWritten is for.

No, it's not.

bytesWritten is emitted whenever QAbstractSocket has written to the socket 
layer. That does not mean that they have been sent to the remote side, much 
less that the other side has ACK'ed them.

There's simply no way to get the number of bytes ACK'ed from the other side. I 
did search the Linux TCP API yesterday and I couldn't find anything suitable. 
And even if there were such a way, the ACK information is useless, since the 
application on the other side may never read from the socket.

Speaking in terms of the OSI model, bytesWritten is the number of bytes 
transferred from the Application layer to the Transport layer[*]. There's no 
equivalent of knowing when such bytes were passed from the Transport to the 
Application layer on the other side.

[*] through Presentation and Session -- QSslSocket muddies this a bit, since 
it's the number of bytes from Transport to Presentation, while 
encryptedBytesWritten is the number of bytes from Presentation to Transport.

> However note that when you e.g. sent 4097 bytes, but the signal reports
> "4096 bytes written (and ACK'ed by the receiver!" that does /not/ (yet)

It doesn't report that. See above.

> imply that one byte was lost! That one byte might just be sitting around in
> some OS / TCP/IP stack-specific buffer waiting to be filled up (keyword:
> "Nagle's algorithm") - and sent later.
> 
> 
> However I said "not entirely" because you might be correct that some APIs
> don't let you know how many bytes were ACK'ed by the counterparty. Qt is
> /not/ one of them. ;)

It is.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
     Intel Sweden AB - Registration Number: 556189-6027
     Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden




More information about the Interest mailing list