El close
call solo marca el socket TCP cerrado. Ya no se puede utilizar por proceso. Pero el núcleo aún puede contener algunos recursos durante un período (TIME_WAIT, 2MLS, etc.).
La configuración de SO_REUSEADDR debería eliminar los problemas de vinculación.
Así que asegúrese de que el valor de true
es realmente distinto de cero cuando se llama a setsockopt
(el error de desbordamiento puede sobrescribirlo):
true = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))
Hay pid
variable es su código. Si usa fork
(para iniciar los procesos de manejo de conexiones), entonces debe cerrar sock
también en el proceso que no lo necesita.
Primero por el nombre, para que todos nombremos las mismas cosas de la misma manera:
Lado del servidor:
El socket pasó a listen()
y luego a accept()
llamemos a la escucha socket. El socket devuelto por accept()
llamemos al aceptado enchufe.
Lado del cliente:
El socket pasó a connect()
llamemos a conectando/conectado enchufe.
Con respecto a su problema:
Para terminar el accept()
ed conexión cerrar el aceptado enchufe (lo que llamas conectado) opcionalmente usando primero shutdown()
seguido de close ()
.
Para luego aceptar un nuevo bucle de conexión justo antes de la llamada a accept()
, no ir a través de bind()
y listen()
de nuevo.
Solo apagar y cierra la escucha socket si desea deshacerse de pendiente connect()
s emitido después de accept()
devuelto.
La conexión aún está activa porque olvidó cerrar el enchufe conectado. Cerrar la toma de escucha no cierra automáticamente la toma conectada.
//necessary code
close(connected); // <---- add this line
close(sock);
goto label;
Sin embargo, no estoy seguro de por qué está tomando EADDRINUSE. El código funcionó bien tanto en Linux como en Mac OS.