limitation connexion serveur linux en c

limitation connexion serveur linux en c - C - Programmation

Marsh Posté le 12-09-2006 à 16:26:26    

Bonjour,
 
Après avoir lu le manuel, les différents sujets du forum et fait pas mal de tests, je souhaiterais avoir des explications au sujet du fonctionnement du listen d'un serveur de socket.
J'ai développé un serveur en C sous linux pour mon entreprise (communication GPRS mais cela ne diffère en rien...).  
Je crée une socket sur laquelle viennent se connecter plusieurs clients, et à chaque connexion je crée un thread que je détache.
Je souhaite pouvoir limiter le nombre de connexion à mon serveur afin de ne pas le faire mouliner pour rien (je ne suis pas le seul à fontionner sur la machine...).
Au départ, je pensais que la valeur backlog du listen (définition : Longueur de la file d'attente par socket des connexions. Dans Linux 2.2, la valeur indiquée dans listen(2) ne correspond qu'à la longueur de la file des sockets déjà établies.) me permettait de bloquer toute nouvelle connexion une fois la limite atteinte (je supposais que linux refusait de lui même les connexions ou alors que l'accept me renvoyait -1) mais ça n'est pas le cas.  
Une fois la socket définie et établie, je fais un select en écoute sur la socket. Dans le cas où j'atteind la limite, le select m'indique toujours que des clients se connectent et l'accept fonctionne aussi donc pas de limitation sauf par mon tableau de thread qui est limité.
Le souci est donc que les connexions à la socket sont acceptées et que même si le client n'est plus connecté, l'accept me fournit le prochain client de la file (connecté ou non avec les datas envoyées) et cela crash dans le cas d'un client non connecté.
 
Pour des raisons de confidentialité, je ne peux vous fournir tout le code mais une partie :
 
Algorithme :  
 - socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)        => création de la socket
 - fcntl(skt_fd,F_SETFL,O_NONBLOCK)                         => socket non bloquante
 - bind                                                                   => assignation d'un nom à la socket
 - listen(skt_fd, 20)                                                  => désir d'accépter des connexions
 - while(1)  
    - select(srv_fd+1, &rfds, NULL, NULL, &timeout)        => attente de réception
         - fd = accept                                                 => acceptation de la connexion
             - si trop de client : close fd
             - sinon : - pthread_create                            => création du thread
                          - pthread_detach
 
Dans ce cas là, cela fonctionne et je gère moi même la limitation en closant les nouvelles connexions. Mais le problème est que dans le cas où je limite, l'accept se fait et je close donc le client émet quand même (coût de communication inutiles).
Donc est il possible que linux fasse la limitation tout seul ? (je préfèrerais ne pas utiliser la fonction sysctl pour modifier le paramêtre tcp_max_syn_backlog qui limite la file des sockets pas encore établies ).
 
Merci.
 
En espèrant avoir été assez clair...
 
Yannick.

Reply

Marsh Posté le 12-09-2006 à 16:26:26   

Reply

Marsh Posté le 12-09-2006 à 16:38:58    

bof. t'as qu'à faire un sémaphore dans ton code et voilà. sinon tu filtres avec iptables et ça sera fait au niveau du firewall.

Reply

Marsh Posté le 12-09-2006 à 18:00:25    

Merci pour ton message.
En fait c'est ce que je fais déjà. J'ai un compteur de connexion. Lorsque j'atteins la limite, le select m'indique une réception, je fais l'accept et je close direct.  
Si je ne fais pas l'accept, le select n'arrête pas de me dire que je reçois quelque chose.
Si je ne fais pas le close et que le produit se déconnecte, l'accept me fournit la connexion du produit déconnecté (autrement dit les datas reçus mais je ne peux répondre).
Ca marche bien comme ça mais j'aurais aimé ne pas faire l'accept pour ne pas faire consommer le client en communication gprs (très très cher...).
Merci.

Reply

Marsh Posté le 12-09-2006 à 21:18:07    

iptables te dis-je.

Reply

Marsh Posté le 12-09-2006 à 21:45:13    

iptables j'ai bien compris mais iptables je ne souhaite pas utiliser car je ne souhaite pas m'aventurer dans ces contrés inconnues...
Si tu n'as pas d'autres solutions merci quand même, quelqu'un d'autre pourra peut être m'aider...

Reply

Marsh Posté le 12-09-2006 à 22:02:37    

Il n'y en pas d'autres. Je ne vois pas pourquoi tu poses des questions si tu ne veux pas des réponses. C'est ridicule comme attitude. Ferme ce sujet, tout le monde gagnera du temps.

Reply

Marsh Posté le 12-09-2006 à 22:12:39    

Tu n'as qu'à utiliser une variable globale protégée en exclusion mutuelle pour compter tes connexions.  
 
Sur ton algo ça donne
- socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)        => création de la socket
 - fcntl(skt_fd,F_SETFL,O_NONBLOCK)                         => socket non bloquante
 - bind                                                                   => assignation d'un nom à la socket
 - listen(skt_fd, 20)                                                  => désir d'accépter des connexions
 - nb_connex=0;
    pthread_mutex_init(&mut,NULL);
 - while(1)  
    - select(srv_fd+1, &rfds, NULL, NULL, &timeout)        => attente de réception
         - fd = accept                                                 => acceptation de la connexion
          pthread_mutex_lock(&mut);
             - si nb_connex==NB_MAX : close fd ; pthread_mutex_unlock(&mut);
             - sinon : nb_connex++; pthread_mutex_unlock(&mut);
                         - pthread_create                            => création du thread
                          - pthread_detach  
 
Quand la connexion (et donc le thread) se termine ne pas oublier de faire:
          pthread_mutex_lock(&mut);
         nb_connex--;
          pthread_mutex_unlock(&mut);

Reply

Marsh Posté le 12-09-2006 à 23:24:28    

Taz : ton incompétence est à la hauteur de ta réponse...Pas la peine de répondre...
TheDuke34 : merci bien, je vais essayer demain.

Reply

Marsh Posté le 13-09-2006 à 10:27:57    

Je vais peut-être dire une bêtise, mais pourquoi tu virerais pas ta socket de connexion de la liste des fd surveillés par le select ?
Il me semble que c'est une solution simple pour éviter d'être "dérangé" par des connexions entrantes lorsque tu as atteint la limite...


---------------
TriScale innov
Reply

Marsh Posté le 13-09-2006 à 10:44:12    

J'ai peur que cela coupe aussi le reste mais pourquoi ne pas essayer.
Merci.
Je vais me débrouiller.
Fermeture du sujet...


Message édité par therealvulcain le 13-09-2006 à 10:53:17
Reply

Sujets relatifs:

Leave a Replay

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