I get a good explanation of problem in mudbytes forum:
Though just marking the connection for deletion, and having the normal game loop
finish sending output is probably a better design for how to do the quit, I think the
problem here stems from how SMAUG handles flush_buffer() when there is a lot of
data to send. Close_socket() does call flush_buffer(), but if there is more then so
much data to send (4k in stock), it will send just part of it (.5k in stock). In the
normal quit, you don't send enough data for this to be a problem, but you are
sending quite a lot more and are probably going over the limit to trigger sending
only part of the output, causing the rest to not ever be sent as the connection
closes. You could just change the limits in flush_buffer(), or have it detect if
this is a closing connection and send all data (like it does now if the mud is going
down). You could do the later by setting a flag on the descriptor, passing a new
bool argument to flush_buffer(), or even using the quitting_char global. But I
would look at flush_buffer() and up the numbers there to at least see if that is
the root problem, even if you do a different final fix.
You probably don't want to hang the MUD while trying to flush the buffer on a quitting connection. If you don't leave the function, until the buffer is flushed, your MUD will keep trying to send until all data is sent. That's why it doesn't force the sending of the entire buffer (although it shouldn't just discard the rest).
I cant' undetstand the the david haley note. What the risk about sending all data to a quitting/renting char?