Limitation du nombre de connexions sur un port

Limitation du nombre de connexions sur un port - C - Programmation

Marsh Posté le 16-11-2010 à 11:28:28    

Bonjour à tous,
 
Je dois écrire un programme serveur sur un port TCP, mais au nombre de connexions limitées (en C/C++ sous Linux). N'étant pas un expert en programmation réseau, je me pose quelques questions sur la manière d'implémenter cette limite.
 
Le résultat des recherches que j'ai faites se concentrent surtout sur la configuration du système (via iptable notamment), mais je préfère gérer cela au niveau du programme.  
L'API socket ne propose pas une pléthore de fonctions, et j'ai envisagé les solutions suivantes :
       - compter le nombre de connexions actives et d'arrêter de faire un "listen" sur la socket lorsque le nombre maximum est atteint
ou:  - si le nombre de connexions actives est atteint, fermer le descripteur retourné par "accept" (puisqu'il n'existe pas de fonction "reject" !)
 
Mais je ne trouve pas ces solutions très propres (surtout la première, où les demandes de connexions s'accumulent !). A vrai dire, je ne sais pas si c'est la bonne manière de procéder...
 
Quelqu'un aurait-il une idée ?
 
Merci d'avance !

Reply

Marsh Posté le 16-11-2010 à 11:28:28   

Reply

Marsh Posté le 16-11-2010 à 11:43:41    

La première solution me parait intéressante.
Si le client continue à envoyer des demandes, elles tomberont en timeout, c'est tout. Cela arrive souvent. L'autre solution serait d'accepter la demande, mais de renvoyer un code disant que le service est indisponible (un genre de 404, ou une redirection ailleurs). Mais si le nombre de demandes est trop grande, cela surchargerait le serveur. Et peut-être que le serveur ne pourrait pas renvoyer ce code d'indisponibilité, et cela finira par un timeout de toutes façons.

Reply

Marsh Posté le 16-11-2010 à 14:17:24    

Merci, ca me rassure ! Je n'ai pas pensé du tout qu'il y aurait un timeout si on n'appelle pas "accept", mais c'est logique. Du coup, la première solution n'est pas si sale, finalement.
 
Et puis allez, zou, une deuxième question pour la route... Je ne veux pas que le serveur reste bloqué indéfiniment dans le "listen", car il doit effectuer d'autres taches régulièrement. Or, la fonction "listen" est bloquante et n'accepte pas de paramètre de timeout. Par conséquent, je l'ai remplacée par un "select" avec un argument timeout non nul. En sortie, j'enchaîne directement avec la fonction "accept" s'il y a une demande de connexion.
 
Est-ce correct, ou faut-il impérativement passer par la fonction "listen" ? Je n'ai pas l'impression que ce soit indispensable, car "select" semble faire exactement la même chose que "listen", à savoir attendre qu'un un descripteur de fichier soit prêt pour une opération de lecture/écriture. C'est juste que... peut-être que "listen" opère des choses en plus vis-à-vis des sockets ?

Reply

Marsh Posté le 16-11-2010 à 16:44:51    

N'est-il pas possible de réaliser ces tâches dans un thread, de cette manière tu laisse ta fonction listen bloquer le (les?) thread(s) serveur(s) et tu fait ton traitement en tâche de fond.


---------------
sheep++
Reply

Marsh Posté le 16-11-2010 à 18:02:34    

L'idée c'est que le thread serveur soit surveillé par un thread de supervision afin que celui-ci puisse relancer le thread serveur en cas d'arrêt inopiné. Pour cela, il faut que le thread serveur puisse donner signe de vie régulièrement, donc interrompe son "listen".
 
Je n'aime pas trop l'idée que le thread serveur lance le "listen" dans un thread à part, parce que si celui-ci est coincé dans l'appel de cette fonction, il n'y a aucun moyen de savoir si le thread à l'écoute est toujours là ou pas.
 
Vous allez me dire : il n'y a qu'à utiliser un signal (SIGUSR1, par exemple) pour sortir le thread de son attente bloquante. Oui, mais NON !! Parce que le fait d'envoyer un signal (même anodin) à un id de thread qui n'existe pas (ou plus) conduit à un arrêt violent de tout le processus (SIGSEGV). Donc les signaux, pour moi, c'est vraiment en dernier recours et vraiment si on ne peut pas faire autrement !
 
Donc l'orientation que je voudrais prendre serai plutôt d'éviter de rester coincé dans un appel de fonction "listen" pour ne pas le nommer. Dommage qu'il n'ait pas été prévu de timeout sur cette fonction !

Reply

Marsh Posté le 16-11-2010 à 19:20:06    

Du coup je te conseil d'aller voir du coté de select:
http://broux.developpez.com/articles/c/sockets/#L4-1

 

Tu pourra mettre un timeout avec ça...

 

EDIT: ah bah tu fais déjà ça :D my bad!


Message édité par h3bus le 16-11-2010 à 22:11:43

---------------
sheep++
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed