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.