views:

984

answers:

3

I am seeing that a small set of message written to a non-blocking TCP socket using write(2) are not seen on the source interface and also not received by the destination.

What could be the problem? Is there any way that the application can detect this and retry?

while (len > 0) {
    res = write (c->sock_fd, tcp_buf, len);
    if (res < 0) {
      switch (errno) {
        case EAGAIN:
        case EINTR:
        <handle case>
        break;
        default:
        <close connection>
      }
    }
    else {
      len -= res;
    }
}
A: 

write() returns the number of bytes written, this might be less than the amount of bytes you send in, and even 0! Make sure you check this and retransmit whatever was dropped (due to not enough buffer space on the NIC or whatever)

Daniel Bruce
I do check for the number of bytes returned. It returns the same number of bytes that i had asked to write. But still request not seen on the interface
+1  A: 

Non blocking write(2) means that whatever the difficulties, the call will return. The proper way to detect what happened is to inspect the return value of the function.

If it returns -1 check errno. A value of EAGAIN means the write did not happen and you have to do it again.

It could also return a short write (i.e. a value less than the size of the buffer you passed it) in which case you’ll probably want to retry the missing part.

If this is happening on short lived sockets also read The ultimate SO_LINGER page, or: why is my tcp not reliable. It explains a particular problem regarding the closing part of a transmission.

when we naively use TCP to just send the data we need to transmit, it often fails to do what we want - with the final kilobytes or sometimes megabytes of data transmitted never arriving.

and the conclusions is:

The best advice is to send length information, and to have the remote program actively acknowledge that all data was received.

It also describes a hack for Linux.

kmkaplan
I am seeing that the write succeeds with whatever I am asking to write. I do check for the return value and for EAGAIN. The return value is the length i had asked to write
+1  A: 

You want to read up on TCP_NODELAY option and the nature of the TCP send buffer.

Nikolai N Fetissov