Eccezione socket: & # 8220; Non ci sono più endpoint disponibili dal mapper endpoint & # 8221;
Domanda
Sto usando Winsock e C ++ per configurare un'applicazione server. Il problema che sto riscontrando è che la chiamata a ascolta
si traduce in un'eccezione della prima possibilità. Immagino che normalmente questi possano essere ignorati (?), Ma ho trovato altri che hanno lo stesso problema: dove l'applicazione si blocca ogni tanto. Qualsiasi aiuto sarebbe molto apprezzato.
L'eccezione della prima possibilità è:
Eccezione per la prima possibilità su 0x * 12345678 * in MyApp .exe: 0x000006D9: non sono disponibili altri endpoint dal mapper endpoint.
Ho trovato alcune prove che questo potrebbe essere causato dal socket e il codice con cui sto lavorando è il seguente. L'eccezione si verifica nella chiamata a ascolta
nella quinta riga dal basso.
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;
}
Soluzione
Su un server molto occupato, si potrebbe essere a corto di socket. Potrebbe essere necessario modificare alcuni parametri TCPIP. Modifica questi due nel registro:
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
MaxUserPort REG_DWORD 65534 (decimal)
TcpTimedWaitDelay REG_DWORD 60 (decimal)
Per impostazione predefinita, ci sono alcuni minuti tra il rilascio di una porta di rete (socket) e il momento in cui può essere riutilizzato. Inoltre, a seconda della versione del sistema operativo, ci sono solo poche migliaia nell'intervallo che Windows utilizzerà. Sul server, eseguilo al prompt dei comandi:
netstat -an
e guarda i risultati (pipe to a file è il più semplice: netstat -an > netstat.txt). Se vedi un numero elevato di porte da 1025- > 5000 nello stato Ritardo attesa temporizzata, questo è il tuo problema e viene risolto regolando la porta utente massima da 5000 a 65534 utilizzando la voce di registro sopra. Puoi anche regolare il ritardo utilizzando la voce di registro sopra per riciclare le porte più rapidamente.
Se questo non è il problema, è probabile che sia il numero di connessioni in sospeso impostate nel metodo Listen ().
Altri suggerimenti
Il problema originale non ha nulla a che fare con winsock. Tutte le risposte sopra sono ERRATE. Ignora l'eccezione della prima possibilità, non è un problema con la tua applicazione, ma solo una gestione degli errori interni.
Stai effettivamente riscontrando un problema, ad esempio il programma termina a causa di un'eccezione non gestita?
Il debugger può stampare il messaggio anche in assenza di problemi, ad esempio, vedere qui .
Uhh, forse è perché stai limitando notevolmente il numero massimo di connessioni in entrata?
listen (m_accept_fd, 5)
// Limit here ^^^
Se si consente un backlog maggiore, si dovrebbe essere in grado di gestire il problema. Usa qualcosa come SOMAXCONN invece di 5.
Inoltre, se il tuo problema è solo all'avvio del server, potresti voler disattivare LINGER (SO_LINGER) per impedire che le connessioni si blocchino e blocchino il socket ...
Questo non risponderà direttamente alla tua domanda, ma dato che stai usando C ++, ti consiglio di usare qualcosa come Boost :: Asio per gestire il tuo codice socket. Questo ti dà una bella astrazione sull'API Winsock e dovrebbe permetterti di diagnosticare più facilmente le condizioni di errore.