2008-11-07 21 views
7

Ich verwende winsock und C++, um eine Server-Anwendung einzurichten. Das Problem, das ich habe, ist, dass der Aufruf an listen eine erste Chance-Ausnahme ergibt. Ich denke, normalerweise können diese ignoriert werden (?), Aber ich habe andere mit dem gleichen Problem gefunden, das ich bin, wo es die Anwendung verursacht, hin und wieder zu hängen. Jede Hilfe würde sehr geschätzt werden.Socket-Ausnahme: "Es sind keine weiteren Endpunkte vom Endpunkt-Mapper verfügbar"

Die erste Chance Ausnahme:

Erste-Chance-Ausnahme bei 0x * 12345678 * in MeineAnw .exe: 0x000006D9: Es sind keine weiteren Endpunkte von der Endpunkt-Zuordnung verfügbar.

Ich habe einige Beweise gefunden, dass dies durch den Sockel verursacht werden könnte. Und der Code, mit dem ich arbeite, ist wie folgt. Die Ausnahme tritt beim Aufruf von listen in der fünften Zeile von unten auf.

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

Wird dieses Abhören nur beim Start durchgeführt? Ist der Port für dich dynamisch? Wie viele Ports hören Sie gleichzeitig? –

Antwort

6

Auf einem sehr ausgelasteten Server sind die Sockets möglicherweise knapp. Möglicherweise müssen Sie einige TCPIP-Parameter anpassen. Passen diese beiden in der Registrierung:

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

Standardmäßig gibt es ein paar Minuten Verzögerung zwischen einem Netzwerkanschluss Freigabe (Buchse) und wenn sie wiederverwendet werden können. Abhängig von der Betriebssystemversion gibt es nur wenige tausend in dem Bereich, den Windows verwenden wird. Auf dem Server, diese Aufforderung zu einem Befehl ausführen:

netstat -an

und Blick auf die Ergebnisse (Rohr in eine Datei ist am einfachsten: netstat -an> netstat.txt). Wenn Sie eine große Anzahl von Ports von 1025-> 5000 im Status "Zeitverzögerte Wartezeiten" sehen, ist dies Ihr Problem, und es wurde gelöst, indem Sie den maximalen Benutzerport von 5000 auf 65534 mithilfe des obigen Registrierungseintrags anpassen. Sie können die Verzögerung auch anpassen, indem Sie den Registrierungseintrag oben verwenden, um die Ports schneller zu recyceln.

Wenn dies nicht das Problem ist, ist das Problem wahrscheinlich die Anzahl der ausstehenden Verbindungen, die Sie in Ihrer Listen() -Methode festgelegt haben.

0

Dies wird Ihre Frage nicht direkt beantworten, aber da Sie C++ verwenden, würde ich empfehlen, so etwas wie Boost::Asio mit Ihrem Socket Code zu behandeln. Dies gibt Ihnen eine schöne Abstraktion über die Winsock-API und sollte es Ihnen ermöglichen, Fehlerbedingungen leichter zu diagnostizieren.

1

Uhh, vielleicht liegt es daran, dass Sie die maximale Anzahl eingehender Verbindungen stark einschränken?

Wenn Sie einen größeren Rückstand erlauben, sollten Sie in der Lage sein, Ihr Problem zu behandeln. Verwenden Sie so etwas wie SOMAXCONN statt 5.

Auch, wenn Ihr Problem nur beim Start des Servers ist, können Sie LINGER (SO_LINGER) ausschalten, um zu verhindern, dass Verbindungen rumhängen und die Blockierung der Steckdose ...

+0

Der Wechsel zu SOMAXCONN hat nicht geholfen, aber das ist sicher ein Tipp, den ich mitnehmen werde. Der LINGER hat auch nicht geholfen :-( –

2

Sehen Sie tatsächlich ein Problem, zB beendet das Programm wegen einer unbehandelten Ausnahme?

Der Debugger kann die Nachricht auch ausdrucken, wenn kein Problem vorliegt, siehe z. B. here.

3

Das ursprüngliche Problem hat nichts mit Winsock zu tun. Alle obigen Antworten sind falsch. Ignoriere die Ausnahme der ersten Chance, es ist kein Problem mit deiner Anwendung, nur eine interne Fehlerbehandlung.