views:

4687

answers:

5

I am using winsock and C++ to set up a server application. The problem I'm having is that the call to listen results in a first chance exception. I guess normally these can be ignored (?) but I've found others having the same issue I am where it causes the application to hang every once in a while. Any help would be greatly appreciated.

The first chance exception is:

First-chance exception at 0x*12345678* in MyApp.exe: 0x000006D9: There are no more endpoints available from the endpoint mapper.

I've found some evidence that this could be cause by the socket And the code that I'm working with is as follows. The exception occurs on the call to listen in the fifth line from the bottom.

  m_accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (m_accept_fd == INVALID_SOCKET)
  {
    return false;
  }

  int optval = 1;

  if (setsockopt (m_accept_fd, SOL_SOCKET, SO_REUSEADDR,
                  (char*)&optval, sizeof(optval)))
  {
    closesocket(m_accept_fd);
    m_accept_fd = INVALID_SOCKET;
    return false;
  }

  struct sockaddr_in  local_addr;
  local_addr.sin_family = AF_INET;
  local_addr.sin_addr.s_addr = INADDR_ANY;
  local_addr.sin_port = htons(m_port);

  if (bind(m_accept_fd, (struct sockaddr *)&local_addr,
           sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  {
    closesocket(m_accept_fd);
    return false;
  }

  if (listen (m_accept_fd, 5) == SOCKET_ERROR)
  {
    closesocket(m_accept_fd);
    return false;
  }
A: 

This won't answer your question directly, but since you're using C++, I would recommend using something like Boost::Asio to handle your socket code. This gives you a nice abstraction over the winsock API, and should allow you to more easily diagnose error conditions.

Harper Shelby
A: 

Uhh, maybe it's because you're limiting greatly the maximum number of incoming connections?

listen (m_accept_fd, 5)
// Limit here       ^^^

If you allow a greater backlog, you should be able to handle your problem. Use something like SOMAXCONN instead of 5.

Also, if your problem is only on server startup, you might want to turn off LINGER (SO_LINGER) to prevent connections from hanging around and blocking the socket...

Douglas Mayle
Changing to SOMAXCONN didn't help, but that's certainly a tip I'll take with me. The LINGER didn't help either :-(
Bryan Marble
+1  A: 

Are you actually seeing a problem, e.g., does the program end because of an unhandled exception?

The debugger may print the message even when there isn't a problem, for example, see here.

David Norman
+4  A: 

On a very busy server, you may be running out of Sockets. You may have to adjust some TCPIP parameters. Adjust these two in the registry:

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
   MaxUserPort  REG_DWORD  65534 (decimal)
   TcpTimedWaitDelay REG_DWORD 60 (decimal)

By default, there's a few minutes delay between releasing a network port (socket) and when it can be reused. Also, depending on the OS version, there's only a few thousand in the range that windows will use. On the server, run this at a command prompt:

netstat -an

and look at the results (pipe to a file is easiest: netstat -an > netstat.txt). If you see a large number of ports from 1025->5000 in Timed Wait Delay status, then this is your problem and it's solved by adjusting up the max user port from 5000 to 65534 using the registry entry above. You can also adjust the delay by using the registry entry above to recycle the ports more quickly.

If this is not the problem, then the problem is likely the number of pending connections that you have set in your Listen() method.

Darian Miller
+1  A: 

The original problem has nothing to do with winsock. All the answers above are WRONG. Ignore the first-chance exception, it is not a problem with your application, just some internal error handling.

a_mole