2008-11-07 31 views
7

Estoy usando winsock y C++ para configurar una aplicación de servidor. El problema que tengo es que la llamada al listen da como resultado una excepción de primera oportunidad. Supongo que normalmente estos pueden ser ignorados (?) Pero he encontrado que otros tienen el mismo problema que yo y causan que la aplicación se cuelgue de vez en cuando. Cualquier ayuda sería muy apreciada.Excepción de socket: "No hay más puntos finales disponibles en el asignador de extremos"

La primera excepción es la oportunidad:

excepción de primera oportunidad en 0x * 12345678 * en MiApl .exe: 0x000006D9: No hay más extremos disponibles desde el asignador de extremos.

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 se produce en la llamada al listen en la quinta línea desde la parte inferior.

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; 
    } 
+0

¿Esta escucha solo se realiza al inicio? ¿El puerto está vinculando a dinámico? ¿Cuántos puertos escuchas en un momento dado? –

Respuesta

6

En un servidor muy ocupado, puede que se esté quedando sin Sockets. Es posible que deba ajustar algunos parámetros de 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 cuando puede ser reutilizado. Además, dependiendo de la versión del sistema operativo, solo hay unos pocos miles en el rango que Windows usará. En el servidor, ejecutar esto en un símbolo del sistema:

netstat-an

y mirar los resultados (tubería a un archivo es más fácil: netstat -an> netstat.txt). Si ve una gran cantidad de puertos de 1025-> 5000 en el estado de Demora de tiempo programado, 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, entonces es probable que el problema sea el número de conexiones pendientes que ha establecido en su método Listen().

0

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

1

Uhh, ¿quizás es porque estás limitando mucho la cantidad máxima de conexiones entrantes?

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

Si permite un retraso mayor, debería ser capaz de manejar su problema. Usar algo como SOMAXCONN en lugar de 5.

Además, si su problema es sólo en el inicio del servidor, es posible que desee desactivar LINGER (SO_LINGER) para evitar conexiones de ocupar espacio y el bloqueo de la toma ...

+0

Cambiar a SOMAXCONN no ayudó, pero sin duda es un consejo que llevaré conmigo. The LINGER tampoco ayudó :-( –

2

¿De verdad estás viendo un problema? Por ejemplo, ¿el programa finaliza debido a una excepción no controlada?

El depurador puede imprimir el mensaje incluso cuando no hay un problema, por ejemplo, consulte here.

3

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

Cuestiones relacionadas