tags:

views:

289

answers:

4

In standard tcp implementations (say, on bsd), does anybody know if it's possible to find out how many bytes have been ack-ed by the remote host? Calling write() on a socket returns the number of bytes written, but I believe this actually means the number of bytes that could fit into the tcp buffer (not the number of bytes written to the network, or the number of bytes acked). Or maybe I'm wrong...

thanks!

A: 

I think you're wrong, although its one of those places where I'd want to look at the specific implementation before I would bet serious money on it. Consider, though, the case of a TCP connection where the connection is dropped immediately after the original handshake. If the number-of-bytes returned were just the number of buffered, it would be possible to apparently have written a number of bytes, but have them remain undelivered; that would violate TCP's guarantee-of-delivery property.

Note, though, that this is only true of TCP; not all protocols within IP provide the same guarantee.

Charlie Martin
TCP guarantees delivery OR notification of failure. Sending a bunch of bytes down the pipe, and then immediately closing the socket can and will cause some bytes to be "lost". Hence the reason for the SO_LINGER option, which will keep the socket alive until all bytes are sent (most of the time).
grieve
A: 

You might have some luck for TCP by using ioctl(fd, TIOCOUTQ, &intval); to get the outgoing queue into intval. This will be the total length kept in the queue, including "written by the app" but not yet sent. It's still the best approximation I can think of at the moment.

dwc
Drat. -1 (error) ; not available on bsd (er, iPhone, that is). To my mind, the tcp stack oughtta have this information. Why doesn't it report it in any way? Maybe there's some deeper reason, but I can't think of it. Thanks for the help!
Drat is right. I should have mentioned that TIOCOUTQ (and TIOCINQ) is not supported everywhere, and even where it is the numbers you get back don't always mean the same thing on each platform.
dwc
+1  A: 

When you have NODELAY=false (which is the default), when you call send() with less bytes than the TCP window, the bytes are not really sent immediately, so you're right. The OS will wait a little to see if you call another send(), in order to use only one packet to transmit the combined data, and avoid wasting a TCP header.

When NODELAY=true the data is transmitted when you call send(), so you can (theoretically) count on the returned value. But this is not recommended due to the added network inefficiency.

All in all, if you don't need absolute precision, you can use the value returned by send() even when NODELAY=true. The value will not reflect immediate reality, but some miliseconds later it will (but also check for lost connections, since the last data block you sent could have been lost). Once the connection is gracefully terminated, you can trust all the data was transmitted. If it wasn't, you'll know before - either because the connection was abruptly dropped or because you received a data retention related error (or any other).

Fabio Ceconello
+1  A: 

I don't know of any way to get this and its probably not useful to you anyway.

Assuming you want to know how much data was received by the host so that after connection lost and re-connection you can start sending from there again. So, the ACK'd data has only been ACK'd by the OS! It doesn't indicate what data has been received by your program on the other side; depending on the size of the TCP receive buffer there, your program could be hundreds of KB behind. If you want to know how much data has been received and 'used' by the program there, then get it to send application-level ACKs

alanjmcf
Hmph - someone's always with the "you don't really want that"...My use case is somewhat prosaic: I want to show a progress bar when uploading a large file from a mobile phone to a server. With such a channel - huge window, huge rtt, having tcp tell me this information makes sense.
:-) Ok, in that scenario... It would be nice to have such a value -- but I guess then people would misuse it. :-,(I guess I'm just used to newbies asking for more than is possible. (I guess I could just refer them to e.g. http://www.joelonsoftware.com/articles/LeakyAbstractions.html)
alanjmcf