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.