2009-02-14 12 views
15

¿Cómo me aseguro de que un socket vinculado a un puerto se libera correctamente en la salida del proceso de modo que el puerto pueda reutilizarse sin bind() que falla con EADDRINUSE? He escrito un pequeño programa que simplemente crea un socket, lo vincula a un puerto fijo, espera una conexión y luego termina inmediatamente. Cuando vuelvo a ejecutar el programa, la llamada bind() falla con EADDRINUSE, pero si espero unos minutos, tiene éxito.Liberación de puertos vinculados en la salida de proceso

¿Hay alguna manera de poder "desvincular" explícitamente el socket, liberando así el número de puerto?

Respuesta

22

El uso de la opción de socket SO_REUSEADDR le permitirá reiniciar el programa sin demora.

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

Pero tenga en cuenta que, técnicamente, el uso de SO_REUSEADDR infringe el protocolo TCP/IP, posibilitando (aunque poco probable) que el próximo programa que vincula ese puerto recoja los paquetes destinados al programa original. –

+0

Excelente, exactamente lo que estaba buscando. – JesperE

3

pila TCP/IP mantiene activo puerto por algún tiempo incluso después de close() - socket permanecerá en TIME_WAIT y TIME_WAIT2 estado.

Si no me equivoco, generalmente demora 2 minutos, así que si necesita usar el mismo puerto, configure inmediatamente la opción SO_REUSEADDR en el zócalo antes de encuadernar, tal como lo sugirió Ivo Bosticky.

2

No es exactamente una respuesta a su pregunta, pero está completo:

En Windows, puede establecer el valor del registro TcpTimedWaitDelay para establecer el tiempo de espera para la liberación de las conexiones TCP cerrados a un precio tan bajo como 30 segundos.

Cuestiones relacionadas