I've taken a lot of wrong steps on this one, but I think I have a solution.
Here's the problem as I see it: We can't cancel that selector key, because if we do that, the socket close will cut off the connection to the client before all the data has flushed through the network. I have validated that the data is all flushed to the byte buffer, but it never gets to the client if there is network slowness and it can't all successfully arrive before the CommandThread gets to the call to close. This can happen even in nc noninteractive mode (as we have observed with several false weekend alerts).
However, if we don't cancel the selector key, we'll potentially see a cancelled key exception or an EOF exception in our selector loops in non-interactive netcat, and that will preemptively close the socket.
So we need to keep the key from being cancelled by our processes to ensure the data gets completely sent, but we also need to ignore errors from selecting this key in the case of a 4lw.
Right now, my solution is a total ugly hack that looks something like:
create a boolean in NIOServerCnxn called "ignoreClose", initally set to false. In checkFourLetterWord, set this boolean to true. In the Factory run loop, if we get a CancelledKeyException, with a NIOServerCnxn attachment, and the boolean set to true, ignore the exception. In doIO, if we get an EOFException (possibly any exception) and this boolean is set to true, ignore the exception. This lets us ignore the effects of a cancelled/closed incoming connection from nc without losing data on the socket for times when a 4lw needs a lot of data to be sent or a distance to send it.
Thoughts on this? It has been a bit of a nightmare to figure out, and my googling seems to indicate that netty won't support nc at all ( https://issues.jboss.org/browse/NETTY-236 ).