GNU/Linux >> Linux Esercitazione >  >> Linux

Come distruggere completamente una connessione socket in C

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.


Linux
  1. Come aumentare il timeout della connessione SSH

  2. Come terminare la connessione SSH che non risponde in Linux?

  3. Come chiudere le porte in Linux?

  4. Come aggiungere una connessione MySQL remota in Linux?

  5. Come chiudere rmiregistry in esecuzione su una determinata porta?

Come forzare Wget a utilizzare la connessione IPv4 o IPv6

Il socket Python non chiude correttamente la connessione

In cosa differiscono SO_REUSEADDR e SO_REUSEPORT?

Come chiudere o reimpostare una connessione pconnect() quando si utilizza PHPRedis e PHP-FPM?

Come sapere se è in uso una connessione ssh ControlMaster

Come trovare l'altra estremità della connessione socket unix?