Eccezione socket: & # 8220; Non ci sono più endpoint disponibili dal mapper endpoint & # 8221;

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

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;
  }
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top