-1

I have a server that uses IOCPs, sockets and overlapped. Initially everything is just wonderful. The listening socket hands off to a newly created socket using AcceptEx on an IOCP. I can handle thousands of connections just fine.

When the server process falls behind in processing, it will close and disconnect the listening port. When it catches back up, it will reestablish the listening port with a new IOCP.

The issue I have run into is that on after reestablishing the listening port, and a new connection arrives, I attempt to accept using the exact same code path as above. The AcceptEx fails with WSAEINVAL.

I know I have left out some details (and the devil is always in the details, no?) -- but would appreciate assistance on where I should be looking.

If a curious soul would like more information, I'd be happy to supply.

  • "Disconnect the listening port" makes no sense, you cannot disconnect a port, only a connected socket. Don't talk about it, post code. – Hans Passant Dec 31 '13 at 22:21
  • delete the port -- as no longer listening. the code is quite substantial, I'm afraid. I am not the original author, just the grunt who gets to fix it. – user2097370 Dec 31 '13 at 22:24
  • "delete the port" makes no sense either. I think he means "closes the listening socket" and/or closes the IOCP. I'm not sure. – selbie Dec 31 '13 at 23:42
  • rough crowd. But I suspect diction precision is necessary or there is too much wiggle room or interpretation. Closes the listening socket is correct. netstat will no longer show the port as being listened on. When the internal situation changes and the server starts listening on the port, AcceptEx fails when accepting a new connection. – user2097370 Jan 01 '14 at 04:40
  • If you think the windows tag crowd is rough, try asking ambiguous questions with your question tagged as C++. Those guys redefine tough love. But I digress... In any case, without you showing any minimal example code that demonstrates the issue, I have to use my psychic powers. My psychic powers suggests that the socket identifier you are passing to AcceptEx as the first parameter is the handle to the socket you closed before you went back to listening with a new socket. – selbie Jan 01 '14 at 10:00

2 Answers2

1

It's hard to guess at what your problem might be given you don't show any source code, but...

  1. There's no need to close the listening socket, simply stop posting new AcceptEx() calls and the server will not be able to accept any new connections.

  2. if you really want to close the listening socket as well then do not close the IOCP and make sure you use the same IOCP when you recreate the listening socket.

Len Holgate
  • 21,282
  • 4
  • 45
  • 92
  • Thanks Len. The architecture of the distributed app is to close the listening socket so the clients no longer connect (immediately) and load balance/fail over to another server. As for part 2 -- why is it important to re-use the same IOCP? Currently, a new IOCP gets associated with the re-established listening port. – user2097370 Jan 02 '14 at 02:42
  • Fair enough re closing the listening socket. If you just stop issuing AcceptEx() then the client connection attempts would take longer to time out and so your fail over wouldn't be as effective. There's no reason to change the IOCP, after all, you probably use the same IOCP for all the data flow I/O. I'm not sure if the "accepted socket" needs to be associated with the same IOCP as the listening socket, but if so that may be the cause of your problem... (I was just trying to remove unnecessary change to narrow down the cause of your problem). – Len Holgate Jan 02 '14 at 08:26
0

I will answer my own question, because I have figured out what the underlying issue was. One thing that was critical to the issue, but was not stated in the problem statement was that the server had sub-processes.

It turns out that while the default behavior in windows is to not have handles inherited by sub-processes, the behavior of winsock is the opposite: handles are inherited by sub-processes unless explicitly set to no-inherit on creation.

Creating sockets with non-inheritable handles solves this problem. I hope that this helps someone out there that runs into this issue.