Excepción de socket: & # 8220; No hay más puntos finales disponibles desde el asignador de puntos finales & # 8221;

StackOverflow https://stackoverflow.com/questions/272523

Pregunta

Estoy usando winsock y C ++ para configurar una aplicación de servidor. El problema que tengo es que la llamada a listen resulta en una excepción de primera oportunidad. Supongo que normalmente se pueden ignorar (?), Pero he encontrado que otros tienen el mismo problema que yo, donde hace que la aplicación se bloquee de vez en cuando. Cualquier ayuda sería muy apreciada.

La excepción de primera oportunidad es:

  

Excepción de primera oportunidad en 0x * 12345678 * en MyApp .exe: 0x000006D9: No hay más puntos finales disponibles desde el mapeador de puntos finales.

He encontrado alguna evidencia de que esto podría ser causado por el socket. Y el código con el que estoy trabajando es el siguiente. La excepción ocurre en la llamada a listen en la quinta línea desde abajo.

  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;
  }
¿Fue útil?

Solución

En un servidor muy ocupado, es posible que se esté quedando sin Sockets. Puede que tenga que ajustar algunos parámetros TCPIP. Ajuste estos dos en el registro:

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

Por defecto, hay un retraso de unos minutos entre la liberación de un puerto de red (socket) y cuándo se puede reutilizar. Además, dependiendo de la versión del sistema operativo, solo hay unos pocos miles en el rango que usarán las ventanas. En el servidor, ejecute esto en el símbolo del sistema:

  

netstat -an

y observe los resultados (la canalización a un archivo es más fácil: netstat -an > netstat.txt). Si ve una gran cantidad de puertos desde 1025- > 5000 en estado de Retardo de espera temporizado, entonces este es su problema y se resuelve ajustando el puerto de usuario máximo de 5000 a 65534 usando la entrada de registro anterior. También puede ajustar el retraso utilizando la entrada de registro anterior para reciclar los puertos más rápidamente.

Si este no es el problema, es probable que el problema sea la cantidad de conexiones pendientes que ha establecido en su método Listen ().

Otros consejos

El problema original no tiene nada que ver con winsock. Todas las respuestas anteriores son incorrectas. Ignore la excepción de primera oportunidad, no es un problema con su aplicación, solo un tratamiento interno de errores.

¿Está realmente viendo un problema, por ejemplo, el programa finaliza debido a una excepción no controlada?

El depurador puede imprimir el mensaje incluso cuando no haya un problema, por ejemplo, consulte aquí .

Uhh, ¿tal vez es porque estás limitando en gran medida el número máximo de conexiones entrantes?

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

Si permite una mayor acumulación, debería poder manejar su problema. Use algo como SOMAXCONN en lugar de 5.

Además, si su problema solo está en el inicio del servidor, es posible que desee desactivar LINGER (SO_LINGER) para evitar que las conexiones cuelguen y bloqueen el socket ...

Esto no responderá su pregunta directamente, pero como está usando C ++, recomendaría usar algo como Boost :: Asio para manejar su código de socket. Esto le brinda una buena abstracción sobre la API de winsock y debería permitirle diagnosticar más fácilmente las condiciones de error.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top