[Stanimir Simeonoff]
Now I'd like to report a relatively minor issue w/ TCPConnection.doSend and
'double-writes' per Unix Network Programming.
The body of the method is like follows:
private void doSend(byte[] data, int offset, int length) throws Exception { // we're using 'double-writes', sending the buffer to the destination in 2 pieces. this would // ensure that, if the peer closed the connection while we were idle, we would get an exception. // this won't happen if we use a single write (see Stevens, ch. 5.13). out.writeInt(length); // write the length of the data buffer first *Util.doubleWrite(data, offset, length, out)*;// should be just: out.write(data, offset, length); out.flush(); // may not be very efficient (but safe) }
The comment claims it uses 'double-writes' in order to capture a missing
connection close by the peer. Firstly, that misled me there were not
buffers involved, so it writes straight to the socket output stream but in
that case out.flush() is a NOP.
If that was the case there would be at least 6 packets per message (when
naggling is disabled) - 4 separate calls to each byte of writeInt and then
2 more for Util.doubleWrite. That looked very suspicious and must have been
caught, so I took a look at the out declaration and it's buffered via
BufferedOutputStream with default 8k buf size which is the better size on
linux (buffers less than 8k are allocated on the stack instead of
malloc/free).
However that means doubleWrite is totally not useful as the output is
buffered anyways.
Also double-write is not useful if there is a reading/polling as RST would
be caught immediately, closing the connection. It's useful only if there is
no reading on the socket and that's quite a corner case.