GNU/Linux >> Linux Esercitazione >  >> Linux

Perché connect() dovrebbe dare EADDRNOTAVAIL?

Controlla questo link

http://www.toptip.ca/2010/02/linux-eaddrnotavail-address-not.html

MODIFICA :Sì, volevo aggiungere altro, ma ho dovuto tagliarlo a causa di un'emergenza

Hai chiuso la presa prima di provare a riconnetterti? La chiusura dirà al sistema che la coppia di socket (ip/porta) è ora libera.

Qui ci sono anche altri elementi da guardare:

  • Se la porta locale è già connessa all'IP e alla porta remoti indicati (ovvero, esiste già una coppia di socket identica), riceverai questo errore (vedi il link al bug di seguito).
  • L'associazione di un indirizzo socket diverso da quello locale produrrà questo errore. se gli indirizzi IP di una macchina sono 127.0.0.1 e 1.2.3.4 e stai tentando di collegarti a 1.2.3.5, otterrai questo errore.
  • EADDRNOTAVAIL:l'indirizzo specificato non è disponibile sulla macchina remota o il campo dell'indirizzo della struttura del nome è tutto zero.

Collegamento con un bug simile al tuo (la risposta è quasi in fondo)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294599

Sembra che il tuo socket sia sostanzialmente bloccato in uno degli stati interni del TCP e che l'aggiunta di un ritardo per la riconnessione potrebbe risolvere il tuo problema come sembra che abbiano fatto in quella segnalazione di bug.


Se non sei disposto a modificare il numero di porte temporanee disponibili (come suggerito da David), o hai bisogno di più connessioni rispetto al massimo teorico, ci sono altri due metodi per ridurre il numero di porte in uso. Tuttavia, sono a vari livelli violazioni dello standard TCP, quindi dovrebbero essere usati con cautela.

Il primo è attivare SO_LINGER con un timeout di zero secondi, forzando il TCP stack per inviare un pacchetto RST e svuotare lo stato della connessione. C'è una sottigliezza, tuttavia:dovresti chiamare shutdown sul descrittore di file socket prima di close , in modo da avere la possibilità di inviare un FIN pacchetto prima del RST pacchetto. Quindi il codice sarà simile a:

shutdown(fd, SHUT_RDWR);
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_LINGER,
           (char *) &linger, sizeof(linger));
close(fd);

Il server dovrebbe vedere una connessione prematura reimpostata solo se FIN pacchetto viene riordinato con RST pacchetto.

Vedere l'opzione TCP SO_LINGER (zero) - quando è richiesta per maggiori dettagli. (Sperimentalmente, non sembra importare dove imposti setsockopt .)

Il secondo è usare SO_REUSEADDR e un bind esplicito (anche se sei il client), che consentirà a Linux di riutilizzare le porte temporanee durante l'esecuzione, prima che finiscano di aspettare. Nota che devi usa bind con INADDR_ANY e la porta 0 , altrimenti SO_REUSEADDR non è rispettato. Il tuo codice sarà simile a:

int opts = 1;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
         (char *) &opts, sizeof(int));

struct sockaddr_in listen_addr;
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = 0;
listen_addr.sin_addr.s_addr = INADDR_ANY;
// todo: test for error
bind(fd, (struct sockaddr *) &listen_addr, sizeof(listen_addr));

// todo: test for addr
// saddr is the struct sockaddr_in you're connecting to
connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));

Questa opzione è meno valida perché continuerai a saturare le strutture dati interne del kernel per le connessioni TCP come da netstat -an | grep -e tcp -e udp | wc -l . Tuttavia, non inizierai a riutilizzare le porte fino a quando ciò non accadrà.


Questo può accadere anche se viene fornita una porta non valida, come 0.


Linux
  1. Perché `md5sum` non fornisce lo stesso hash di Internet?

  2. Perché è rischioso dare accesso a Sudo Vim agli utenti ordinari?

  3. Ssh – Perché Ssh impiega molto tempo per connettersi?

  4. Errore durante il tentativo di connessione a VPN all'avvio?

  5. Impossibile connettersi all'errore 111 del server MySQL

Errore del server FTP RHEL7:ftp:connessione:nessun percorso verso la soluzione host

Perché viene visualizzato l'errore:snap "xyz" non trovato?

Perché rsync su SSH mi offre un throughput 10 volte superiore a quello di SCP?

apache2.4 con webdav restituisce un errore 405

Perché chmod +w non concede il permesso di scrittura ad altri(o)

Perché sono necessari < o > per usare /dev/tcp