Bonjour,
Je suis actuellement entrain d'écrire un programme permettant de répartir des calculs sur des machines a l'intérieur d'un réseau local (en l'occurrence un cluster de calcul).
Les machines sont sous Debian Testing avec un kernel Linux 3.2.0-3-amd64.
Le programme en question ressemble donc un peu a un serveur web, c'est un modèle client/serveur.
1) Le serveur sélectionne les données a calculer puis se met en attente d'une connexion TCP.
2) Le client initie la connexion TCP avec connect() puis récupère les données a calculer.
3) Le client calcule.
4) Le client initie une seconde connexion TCP pour transférer les résultats et retourne a l'étape 2.
Évidement, tout cela est géré par un petit protocole home-made.(je n'entrerais pas dans les détails)
Comme vous pouvez le voir cette manière de procéder permet aux multiples clients de faire des calculs en parallèle si le temps de calcul est bien plus long que le transfert des données (ce qui est très souvent le cas).
En fait cela marche plutôt bien sauf que pour certains calculs, il arrive que le temps de traitement d'un paquet de données soit si court que le serveur traite plusieurs milliers de connexions TCP a la seconde.
Et là, ça se gate vraiment, le serveur tiens le coup il n'y a pas de probleme, par contre les clients eux terminent sur un retour -1 de l'appel système connect() avec l'erreur EADDRNOTAVAIL.
Et franchement je ne sait pas comment éviter ça!
J'ai essayé de vérifier errno au retour de connect() et si il est égal a EADDRNOTAVAIL d'attendre 1 seconde mais très rapidement, ça repart dans le decort!
Si dessous le code:
Le problème semble venir du fait que tout les ports disponibles sont pris a un instant donné.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 while (connect(*sock, (struct sockaddr *) addr, sizeof (struct sockaddr_in)) < 0) { if (errno == EADDRNOTAVAIL) { perror("connect in request_connexion"); fprintf(stderr,"sleeping 1 seconde before retrying connect...\n"); sleep(1); } else { perror("connect in request_connexion"); return(EXIT_FAILURE); } }
Bref, j'aimerais savoir comment être sur que connect() puisse attribuer une identité a sock ou bien attendre a la fin de la connexion la libération du port par le noyau.
Merci.
Partager