2009-02-14 4 views
15

Come si assicura che un socket associato a una porta sia correttamente rilasciato all'uscita del processo in modo tale che la porta possa essere riutilizzata senza l'errore bind() con EADDRINUSE? Ho scritto un piccolo programma che crea solo un socket, lo lega a una porta fissa, aspetta una connessione e termina immediatamente. Quando si esegue nuovamente il programma, la chiamata bind() non riesce con EADDRINUSE, ma se si attende alcuni minuti, ha esito positivo.Rilascio delle porte associate all'uscita del processo

Esiste un modo per "separare" esplicitamente il socket, liberando in tal modo il numero di porta?

risposta

22

L'utilizzo dell'opzione socket SO_REUSEADDR consente di riavviare il programma senza ritardo.

int iSetOption = 1; 
... 
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&iSetOption, 
     sizeof(iSetOption)) 
...   
+0

Ma si noti che tecnicamente, l'utilizzo di SO_REUSEADDR viola il protocollo TCP/IP, rendendo possibile (anche se improbabile) per il prossimo programma che associa quella porta a raccogliere i pacchetti destinati al programma originale. –

+0

Eccellente, esattamente quello che stavo cercando. – JesperE

3

stack TCP/IP tiene porto occupato per qualche tempo anche dopo close() - presa rimarrà in TIME_WAIT e TIME_WAIT2 Stato.

Se non sbaglio, di solito ci vogliono 2 minuti, quindi se avete bisogno di utilizzare la stessa porta impostato immediatamente SO_REUSEADDR opzione sul socket prima vincolante, proprio come Ivo Bosticky suggerito.

2

Non esattamente una risposta alla tua domanda, ma per completezza:

In Windows è possibile impostare il valore del Registro TcpTimedWaitDelay per impostare il timeout per rilasciare le connessioni TCP chiuse a partire da 30 secondi.