The difference between disconnecting "true" and "false" in lNet is that with "true" you force a hard disconnect and lose any "on the way" data (you close the door both in and out). If you use false, you only close the "sending" side of the socket and wait for the other side to close theirs.
The reason why your sockets "linger" is due to no events happening. I think this is a bit of a logical oversight (although not critical). Basically, when a socket gets disconnected it turns "FDispose" flag to true. When the "event handler" finishes it's run it looks for all to-be-disposed sockets and frees them (this is when count goes down in TLTcp). I think you found a logical bug in the case that server-side user-event causes a hard disconnect on the socket. While the connection does go off it doesn't free the socket since no event took place and nobody actually found out about the dispose flag.
If you use "soft" disconnect, you actually cause an event to happen (the other side "affirms" your closing) and thus it works that way. I'll have to think about what to do with hard disconnects on eventers when called from the user.
So basically for now, use soft disconnects (they are the "proper" way from TCP standpoint too). The OnReceive you get is ok (you get the "recv = 0 => connection receive endpoint closed"). Since lNet doesn't use internal buffers, you must always call "recv" even if you're "receiving a disconnect"
I'll think about what to do with hard "user-side" disconnects (it's not as easy as it may sound actually, because I can't just free the socket at that time, and adding a new callback to the eventer seems hackish to me).
Currently hard disconnects are default but it's a compatibility thing (since before 0.5.x I used hard disconnects always). I'll switch to soft ones by default in 0.7.x.