Il close
call contrassegna solo il socket TCP come chiuso. Non è più utilizzabile dal processo. Ma il kernel potrebbe ancora contenere alcune risorse per un periodo (TIME_WAIT, 2MLS ecc.).
L'impostazione di SO_REUSEADDR dovrebbe rimuovere i problemi di binding.
Quindi assicurati che il valore di true
è davvero diverso da zero quando si chiama setsockopt
(il bug di overflow potrebbe sovrascriverlo):
true = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))
C'è pid
variabile è il tuo codice. Se usi fork
(per avviare i processi di gestione della connessione), allora dovresti chiudere sock
anche nel processo che non ne ha bisogno.
Innanzitutto per la denominazione, quindi chiamiamo tutti le stesse cose allo stesso modo:
Lato server:
Il socket è passato a listen()
e poi a accept()
chiamiamo l'ascolto socket.Il socket restituito da accept()
chiamiamo gli accettati presa.
Lato client:
Il socket è passato a connect()
chiamiamo connessione/connesso presa.
Per quanto riguarda il tuo problema:
Per terminare il accept()
ed connessione chiudi accettata presa (quello che tu chiami connesso) utilizzando facoltativamente prima shutdown()
seguito da close ()
.
Per poi accettare un nuovo ciclo di connessione subito prima della chiamata a accept()
, non passa attraverso bind()
e listen()
di nuovo.
Solo arresto e chiudi l'ascolto socket se vuoi sbarazzarti di pending connect()
s rilasciato dopo accept()
restituito.
La connessione è ancora attiva perché hai dimenticato di chiudere la presa connessa. La chiusura del socket di ascolto non chiude automaticamente il socket connesso.
//necessary code
close(connected); // <---- add this line
close(sock);
goto label;
Non sono sicuro però del motivo per cui stai ricevendo EADDRINUSE. Il codice ha funzionato bene sia su Linux che su Mac OS.