02 Jun, 2009, Banner wrote in the 1st comment:
Votes: 0
Is there a way to make the quit command wait until everything is sent before it completely logs the player out? I have several messages and whatnot I'd like players to receive on exiting the game, however, hardly any of it gets entirely through before the game kills the connection like so:

Everything begins to fade black .. and then … nothing.

A strange voice says, 'See you again, Banner .. real soon..'

EXIT_GREETING
——————————————————————————–


____ _ _ _ ___ _ _ _
/ ___| __ _| | __ _ ___| |_(_) ___ |_ _|_ __ ___(_) __ _| |__ | |_ ___
| | _ / _` | |/ _` |/ __| __| |/ __| | || '_ \/ __| |/ _` | '_ \| __/ __|
| |_| | (_| | | (_| | (__| |_| | (__ | || | | \__ \ | (_| | | | | |_\__ \.
\____|\__,_|_|\__,_|\___|\__|_|\___| |___|_| |_|___/_|\__, |_| |_|\__|___/
|___/

Date Modified: Mon Nov 19 23:51:41 2007
Modified By: Banner
——————————————————————————–

Random Qu

^^ cuts off above with about 3 more lines to send
02 Jun, 2009, David Haley wrote in the 2nd comment:
Votes: 0
Well, sure. Just make sure to send all data in a connection's output buffer before actually closing the connection. I thought this was a default feature of the networking code?
02 Jun, 2009, Banner wrote in the 3rd comment:
Votes: 0
David Haley said:
Well, sure. Just make sure to send all data in a connection's output buffer before actually closing the connection. I thought this was a default feature of the networking code?

The call to close the connection is after all the printfs if that is what you mean.
02 Jun, 2009, Tyche wrote in the 4th comment:
Votes: 0
Banner said:
The call to close the connection is after all the printfs if that is what you mean.


The close call should occur after the output loop does it's send/write. One way to do that is instead of closing the socket in quit, you mark the descriptor with a flag indicating it should be closed.
The add a loop after the output loop the process all the descriptors and close those with the close flag on.
02 Jun, 2009, Kline wrote in the 5th comment:
Votes: 0
Look at your close_socket(). You should be able to drop this at the top of the function as a Dikurivitive.
if( dclose->outtop > 0 )
process_output( dclose, FALSE );
02 Jun, 2009, Banner wrote in the 6th comment:
Votes: 0
process_output is undefined and not found anywhere else in my code, although I did find this:

/*              
* flush outbuf
*/
if( !force && dclose->outtop > 0 )
flush_buffer( dclose, FALSE );
02 Jun, 2009, David Haley wrote in the 7th comment:
Votes: 0
Well, you don't want to force a total flush as that can hang the MUD while flushing the buffer. What you really want to do is to keep processing the socket in the normal way until the output buffer is empty, disallowing all input, and then disconnect the socket. It might help to have some kind of timeout (5min? … whatever) in case it doesn't flush in some reasonable delay.
02 Jun, 2009, tphegley wrote in the 8th comment:
Votes: 0
In your do_quit function, can't you just print what you need before doing all the disconnecting stuff?
02 Jun, 2009, Banner wrote in the 9th comment:
Votes: 0
tphegley said:
In your do_quit function, can't you just print what you need before doing all the disconnecting stuff?

Banner said:
David Haley said:
Well, sure. Just make sure to send all data in a connection's output buffer before actually closing the connection. I thought this was a default feature of the networking code?

The call to close the connection is after all the printfs if that is what you mean.
02 Jun, 2009, David Haley wrote in the 10th comment:
Votes: 0
You don't want to actually close the connection after sending to it – that will immediately close it, even if the buffer has not been sent yet. When you call send_to_char or ch_printf it doesn't immediately send the bytes down the socket, it sticks them onto the output buffer and only later are they actually sent.
02 Jun, 2009, Banner wrote in the 11th comment:
Votes: 0
David Haley said:
You don't want to actually close the connection after sending to it – that will immediately close it, even if the buffer has not been sent yet. When you call send_to_char or ch_printf it doesn't immediately send the bytes down the socket, it sticks them onto the output buffer and only later are they actually sent.
How would you allow it to process the buffer first, or introduce a timeout? Precisely what functions would I need?
02 Jun, 2009, David Haley wrote in the 12th comment:
Votes: 0
You would need some kind of marker on the socket object to note that it is in the process of being closed. The normal output routine already takes care of sending output when possible. You would need to have it close sockets with no pending I/O, and with the closing marker. As for a timeout, you can have some kind of last-activity time stamp.

As I said, I thought all of this was already standard in FUSS for example, so you might want to look there before working on this too much.
03 Jun, 2009, Sharmair wrote in the 13th comment:
Votes: 0
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.
03 Jun, 2009, David Haley wrote in the 14th comment:
Votes: 0
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).
0.0/14