views:

256

answers:

2

Imagine you have a server which can handle only one client at a time. The server uses WSAAsyncSelect to be notified of new connections. In this case, what is the best way of handling FD_ACCEPT messages:

A > Accept the connection attempt right away but queue the client until its turn?

B > Do not accept the next connection attempt until we are done serving the currently connected client?

What do you guys think is the most efficient?

+1  A: 

Ask yourself: what do you want the user experience to be at the other end? Do you want them to be stuck? Do you want them to time out? Do you want them to get a polite message?

bmargulies
Ah... Didn't think about that.So if I don't accept the connection, then the client's connect() attempt will timeout?
Meta
@Meta I'm not 100% sure whether the Windows TCP stack finishes the connection handshake before you call accept or only *if* you call accept. If the former, you get a hang either way. if the later, not calling accept will lead to a connection timeout.
bmargulies
+1  A: 

Here I describe the cons that I'm aware for both options. Hopefully this might help you decide.

A)

  • Upon a new client connection, it could send tons of data making your receive buffer become full, which causes unnecessary packets to be transmitted (see this). If you don't plan to receive any data from the client, shutdown receiving on that socket, thus if the client sends any data after that, the connection is reset. Moreover, if your protocol has strict rules, disconnect the client.
  • If the connection stays idle for too long, the system might disconnect it. To solve this, use setsockopt to set SO_KEEPALIVE on each client socket.

B)

  • If you don't accept the connection after a certain period (I guess the default is 60 seconds), it will timeout. In a normal (or most common) situation this indicates the server is overloaded, thus unable to answer in time. However, if the client is also designed by you, make the socket non-blocking, try to connect, then manage the timeout as you wish.
jweyrich
About (A):If you don't receive on an accepted connection - yes, your receive buffer becomes full. But AFAIK this has nothing to do with retransmits.Instead the TCP window will disappear, so that the other party won't be able to send any more. Not because its send buffer is full, but rather because the TCP window is zero.So that no retransmits will occur. This is what seems to me, but I'm not sure. This seems the most logical things (that's what the "window" field in TCP header for). But I suspect this may depend on the OS implementation of the TCP state machine.
valdo
@valdo: Well spotted, thanks! When the receiving buffer becomes full, the receiver sets the window size to 0, and the sender stops sending data until an ACK is received. Updating my answer.
jweyrich