web-dev-qa-db-fra.com

Impossible d'attribuer l'adresse demandée - causes possibles?

J'ai un programme qui se compose d'un serveur maître et de serveurs esclaves distribués. Les serveurs esclaves envoient des mises à jour d'état au serveur, et si le serveur n'a pas entendu parler d'un esclave spécifique dans une période fixe, il marque l'esclave comme arrêté. Cela se produit régulièrement.

En inspectant les journaux, j'ai constaté que l'esclave ne peut envoyer qu'une seule mise à jour d'état au serveur, puis ne peut jamais envoyer une autre mise à jour, échouant toujours lors de l'appel à la connexion () "Impossible d'attribuer l'adresse demandée (99).

Curieusement, l'esclave est capable d'envoyer plusieurs autres mises à jour au serveur, et toutes les connexions se font sur le même port. Il semble que la cause la plus courante de cet échec soit que les connexions soient laissées ouvertes, mais j'ai du mal à trouver quoi que ce soit laissé ouvert. Y a-t-il d'autres explications possibles?

Pour clarifier, voici comment je me connecte:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

Ce code est dans une fonction pour obtenir une connexion à un autre serveur, et un échec sur l'un de ces 4 appels entraîne l'échec de la fonction.

20
dbeer

Peut-être que SO_REUSEADDR aide ici? http://www.unixguide.net/network/socketfaq/4.5.shtml

9
Michel

Il s'avère que le problème était vraiment que l'adresse était occupée - l'occupation était causée par d'autres problèmes dans la façon dont nous gérons les communications réseau. Vos contributions m'ont aidé à comprendre cela. Merci.

EDIT: pour être précis, les problèmes de gestion de nos communications réseau étaient que ces mises à jour de statut seraient constamment renvoyées si la première échouait. Ce n'était qu'une question de temps jusqu'à ce que chaque esclave distribué essaie d'envoyer sa mise à jour d'état en même temps, ce qui saturait notre réseau.

7
dbeer

ce n'est qu'un tir dans le noir: lorsque vous appelez connect sans liaison en premier, le système alloue votre port local, et si vous avez plusieurs threads se connectant et se déconnectant, il pourrait éventuellement essayer d'allouer un port déjà utilisé. le fichier source du noyau inet_connection_sock.c fait allusion à cette condition. tout comme une expérience, essayez d'abord de faire une liaison avec un port local, en vous assurant que chaque liaison/connexion utilise un numéro de port local différent.

5
dmh2000