GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi connect() donnerait EADDRNOTAVAIL ?

Consultez ce lien

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

MODIFIER :Oui, je voulais en ajouter mais j'ai dû le couper là en raison d'une urgence

Avez-vous fermé la prise avant d'essayer de vous reconnecter ? La fermeture indiquera au système que la paire de sockets (ip/port) est maintenant libre.

Voici des éléments supplémentaires que vous pouvez également consulter :

  • Si le port local est déjà connecté à l'adresse IP et au port distants donnés (c'est-à-dire qu'il existe déjà une paire de sockets identique), vous recevrez cette erreur (voir le lien du bogue ci-dessous).
  • Lier une adresse de socket qui n'est pas l'adresse locale produira cette erreur. si les adresses IP d'une machine sont 127.0.0.1 et 1.2.3.4, et que vous essayez de vous lier à 1.2.3.5, vous allez obtenir cette erreur.
  • EADDRNOTAVAIL :l'adresse spécifiée n'est pas disponible sur la machine distante ou le champ d'adresse de la structure du nom ne contient que des zéros.

Lien avec un bug similaire au vôtre (la réponse est proche du bas)

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

Il semble que votre socket soit essentiellement bloqué dans l'un des états internes TCP et que l'ajout d'un délai de reconnexion pourrait résoudre votre problème, comme ils semblent l'avoir fait dans ce rapport de bogue.


Si vous ne souhaitez pas modifier le nombre de ports temporaires disponibles (comme suggéré par David) ou si vous avez besoin de plus de connexions que le maximum théorique, il existe deux autres méthodes pour réduire le nombre de ports utilisés. Cependant, ils sont à divers degrés des violations de la norme TCP, ils doivent donc être utilisés avec précaution.

La première consiste à activer SO_LINGER avec un délai d'attente de zéro seconde, forçant le TCP pile pour envoyer un paquet RST et vider l'état de la connexion. Il y a cependant une subtilité :vous devez appeler shutdown sur le descripteur de fichier socket avant de close , afin que vous puissiez envoyer un FIN paquet avant le RST paquet. Ainsi, le code ressemblera à :

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);

Le serveur ne devrait voir une réinitialisation de connexion prématurée que si le FIN le paquet est réorganisé avec le RST paquet.

Voir l'option TCP SO_LINGER (zéro) - quand elle est requise pour plus de détails. (Expérimentalement, peu importe où vous définissez setsockopt .)

La seconde consiste à utiliser SO_REUSEADDR et un bind explicite (même si vous êtes le client), ce qui permettra à Linux de réutiliser les ports temporaires lors de l'exécution, avant qu'ils n'aient fini d'attendre. Notez que vous devez utilisez bind avec INADDR_ANY et le port 0 , sinon SO_REUSEADDR n'est pas respecté. Votre code ressemblera à :

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));

Cette option est moins bonne car vous saturerez toujours les structures de données internes du noyau pour les connexions TCP selon netstat -an | grep -e tcp -e udp | wc -l . Cependant, vous ne commencerez pas à réutiliser les ports tant que cela ne se produira pas.


Cela peut également se produire si un port invalide est donné, comme 0.


Linux
  1. Pourquoi obtenez-vous cp:omission d'une erreur de répertoire sous Linux et comment résoudre

  2. Pourquoi `md5sum` ne donne-t-il pas le même hachage qu'Internet ?

  3. Erreur lors de la tentative de connexion au VPN au démarrage ?

  4. Pourquoi fclose(NULL) de la glibc provoque une erreur de segmentation au lieu de renvoyer une erreur ?

  5. Pourquoi ENOENT signifie-t-il Aucun fichier ou répertoire de ce type ?

Erreur de serveur FTP RHEL7 :ftp :connexion :aucune route vers la solution hôte

Pourquoi voyez-vous l'erreur :snap "xyz" introuvable ?

Impossible de se connecter au serveur MySQL erreur 111

Pourquoi wget'ing une image me donne-t-il un fichier, pas une image ?

Pourquoi rsync sur SSH me donne-t-il 10 fois le débit de SCP ?

Pourquoi quelqu'un voudrait-il exécuter UserMode Linux (UML)