Errore: indirizzo già in uso durante il binding del socket con l’indirizzo ma il numero di porta è mostrato gratuitamente da `netstat`

Ho provato a colbind il mio socket (socket del server) alla porta numero 8000 . Ha funzionato e ha fatto il lavoro per me. Alla fine del codice chiudo anche il socket. L’istante successivo eseguo di nuovo il mio codice e mi mostra che l’indirizzo è già in uso. Ho stampato il significato dei valori di errore strerror(errno); per vedere se il mio codice funziona correttamente in ogni punto. Per verificare se la porta è libera, l’ho controllata usando netstat ma mostra che il numero di porta 8000 è gratuito. È successo con me un sacco di volte. Ogni volta quindi aspetto ancora qualche secondo e poi ricomincia a funzionare. Sto usando il linguaggio c. Quindi, qual è la ragione per questo comportamento dal mio sistema operativo.

Dopo alcuni secondi eseguo il codice e poi funziona.

 [email protected]:~/Desktop/testing$ sudo ./a.out Socket Creation: Success File open: Success Socket Bind: Address already in use Socket Listen: Address already in use ^C [email protected]:~/Desktop/testing$ sudo netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1348/lighttpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 984/sshd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1131/cupsd tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1211/mysqld tcp6 0 0 :::22 :::* LISTEN 984/sshd tcp6 0 0 ::1:631 :::* LISTEN 1131/cupsd [email protected]:~/Desktop/testing$ sudo ./a.out Socket Creation: Success File open: Success Socket Bind: Address already in use Socket Listen: Address already in use ^C [email protected]:~/Desktop/testing$ 

Ho incontrato anche lo stesso problema. È perché stai chiudendo la tua connessione al socket, ma non al socket stesso. Il socket può entrare in uno stato TIME_WAIT (per garantire che tutti i dati siano stati trasmessi, TCP garantisce la consegna se ansible) e impiegare fino a 4 minuti per il rilascio .

oppure, per una spiegazione VERAMENTE dettagliata / tecnica, controlla questo link

Può essere fastidioso per essere sicuro, ma non c’è un modo reale intorno ad esso e non è un bug.

So che è passato un po ‘di tempo da quando è stata posta la domanda, ma sono riuscito a trovare una soluzione:

 int sockfd; int option = 1; sockfd = socket(AF_INET, SOCK_STREAM, 0); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); 

Questo imposta la presa che può essere riutilizzata immediatamente.

Mi scuso se questo è “sbagliato”. Non ho molta esperienza con le prese

Prova netstat in questo modo: netstat -ntp , senza il -l . Mostrerà la connessione tcp nello stato TIME_WAIT .

Basta digitare

 unlink [SOCKET NAME] 

nel terminale, quindi l’errore non dovrebbe più esistere.

Come già detto, probabilmente il tuo socket entrerà nello stato TIME_WAIT . Questo problema è ben descritto da Thomas A. Fine qui .

Per riassumere, il processo di chiusura del socket segue lo schema seguente:

Chiusura della presa di corrente

Thomas dice:

Osservando lo schema sopra, è chiaro che TIME_WAIT può essere evitato se l’estremità remota inizia la chiusura. Quindi il server può evitare problemi lasciando che il client si chiuda per primo. Il protocollo dell’applicazione deve essere progettato in modo che il client sappia quando chiudere. Il server può chiudere in sicurezza in risposta a un EOF dal client, tuttavia dovrà anche impostare un timeout quando è in attesa di un EOF nel caso in cui il client abbia lasciato la rete in modo non corretto. In molti casi è sufficiente attendere alcuni secondi prima che il server si chiuda.

L’uso di SO_REUSEADDR è comunemente consigliato su Internet, ma Thomas aggiunge:

Stranamente, l’uso di SO_REUSEADDR può effettivamente portare a errori più “indirizzi già in uso”. SO_REUSADDR ti consente di utilizzare una porta bloccata in TIME_WAIT , ma non puoi ancora utilizzare quella porta per stabilire una connessione all’ultimo posto a cui è connessa. Che cosa? Supponiamo di selezionare la porta locale 1010 e di connettermi alla porta 300 di foobar.com e quindi chiudere localmente, lasciando quella porta in TIME_WAIT . Posso riutilizzare la porta locale 1010 subito per connetterti ovunque tranne che per la porta 300 di foobar.com .

Anche la risposta di icfantv a questa domanda è già perfetta, ho ancora più risultati nel mio test.

Come socket del server in stato di ascolto, se solo in stato di ascolto, e anche accetta richieste e recupera dati dal lato client, ma senza alcuna azione di invio dati. Potremmo ancora riavviare il server immediatamente dopo che è stato arrestato. Ma se qualsiasi azione di invio di dati avviene sul lato server al client, lo stesso riavvio del servizio (stessa porta) avrà questo errore: (Indirizzo già in uso).

Penso che questo sia causato dai principi di progettazione TCP / IP. Quando il server invia i dati al client, deve assicurarsi che l’invio dei dati abbia esito positivo, per fare ciò, il sistema operativo (Linux) deve monitorare la connessione anche se l’applicazione server ha chiuso questo socket. Ma credo ancora che il progettista di socket del kernel possa migliorare questo problema.

l’errore che ho ricevuto è stato:

 cockpit.socket: Failed to listen on sockets: Address already in use 

la correzione che ho scoperto è:

  1. Ho dovuto disabilitare selinux
  2. in / usr / lib / systemd / system / cockpit service ho cambiato linea:

     #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws --selinux-type=etc_t 

    a:

     #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws 

così come puoi vedere ho tirato fuori l’argomento su selinux e poi ho eseguito:

 systemctl daemon-reload systemctl start cockpit.service 

quindi ho navigato per:

Ho accettato il certificato autofirmato e sono riuscito ad accedere correttamente al cockpit e ad usarlo normalmente.

questo è tutto su una macchina fedora25. la porta 9090 era già stata aggiunta usando firewall-cmd

Per AF_UNIX puoi usare call unlink (path); dopo il socket close () nell’app “server”