[Winsock2, IOCP] What is the best way to close a listening socket and then at a future time re-establish on the same port? RRS feed

  • Question

  •  If this is the wrong forum to ask, please redirect me to the correct one.

    I am working in an existing code base (C++) that is using IOCP and winsock2. The basic setup is the server establishes a listening socket on a specific port. Clients connect and acceptEx always works. I always have a pending AcceptEx waiting for new clients. When the socket is accepted, the ephemeral port is used and everyone is happy. 

    Under load, the server may decide to close the listening socket,  obviously disallowing new connections. The previously accepted sockets continue to work -- until the client decides it is not making any progress -- in which case the client closes the socket and will try either another server, or the same.  

    When the server's congestion abates, it will create a new listening socket on the same port. When this happens, the very first AcceptEx returns an invalid parameter. The searching I've done leads me to believe the accepting socket is already connected. Without going too far into this, the code has a collection of re-usable socket and will complicate this discussion. Instead, I modified the code to always get a new socket before calling AcceptEx -- An in this case, when re-establishing the listening socket/port the immediate acceptEx returns IO has been aborted. 

    Without using IOCPs the code functions well (establish, close, re-establish) -- but in order to scale, I'm looking to use IOCPs. Is there something obvious that I am doing or not doing with IOCPs to accomplish what I want to do?

    Wednesday, April 23, 2014 7:22 PM

All replies

  • I am here to answer my own question, in the hopes it doesn't bite someone else.

    One item from the description that appears to be critical is that this server has sub-processes. 

    The fundamental issue, it seems, is that although the default behavior for windows sub-processes is to not inherit handles, winsock is the exception. And although I don't have kernel sources to corroborate, by forcing sockets handles to be non-inheritable fixes the issue, I can only surmise that when the parent closes the listening port, the handle is still open in the sub-process and when re-established, everything is in a bad state when using IOCPs. 

    Tuesday, May 13, 2014 10:08 PM