Je suis encore novice en matière de programmation en socket C mais j'ai pu créer quelques programmes clients et serveurs simples. Je programme un serveur qui écoute les connexions TCP, son rôle est de répondre aux demandes des clients et de fermer la communication lorsque le client envoie une séquence spéciale d'octets (ou lorsqu'il se déconnecte, bien sûr).
J'ai commencé à coder le serveur en utilisant le accept()
à l'intérieur d'une boucle sans fin : le serveur attend un client, l'accepte(), fait tout ce qu'il faut, ferme() le descripteur de socket à la fin et recommence en attendant d'accepter un nouveau client.
Comme je veux servir un seul client à la fois, j'ai appelé la fonction listen de cette façon : listen(mysocket, 1);
Tout fonctionnait plutôt bien, mais un nouveau problème est apparu. La partie serveur expliquée ci-dessus fonctionne dans un thread séparé (appelons-le thread #2) et le thread principal (thread #1) doit pouvoir lui dire de se terminer. J'ai donc créé une variable globale, si cette variable est mise à 1 (par le thread #1) le thread #2 doit se terminer. Le problème est que le thread #2 reste bloqué lorsque la variable globale est activée. accept()
est appelée, elle ne peut donc pas vérifier périodiquement la variable globale.
J'avais clairement besoin d'une valeur de temporisation pour cette fonction : "s'il n'y a pas de connexion à accepter, vérifiez la valeur de la variable globale, continuez à attendre une nouvelle connexion si elle vaut 0 ou terminez si elle vaut 1".
J'ai alors cherché une solution sur Google et j'ai trouvé que la select()
La fonction fait la chose dont j'ai besoin. C'est un peu différent cependant, j'ai découvert pour la première fois la fonction fd_set
et toutes les macros FD_*. J'ai modifié la partie serveur pour qu'elle fonctionne avec la fonction select()
et tout fonctionne très bien, mais voici le dernier problème, celui que je ne parviens pas à résoudre. Si on appelle la fonction listen de cette façon : listen(socket, 1);
mais le serveur accepte et sert toujours plusieurs connexions en même temps. Cela dépend-il du fait que select()
fonctionne avec les fd_set ? J'utilise quelques exemples que j'ai trouvés sur le web et, lorsqu'une connexion est acceptée, elle crée un nouveau descripteur de socket qui va dans l'ensemble avec tous les autres. J'aimerais accepter la connexion d'un seul client, j'ai écrit un code simple qui reconnaît si le client qui se connecte doit être servi ou non, mais y a-t-il un moyen de le déconnecter côté serveur ? Je sais que je dois utiliser la fonction close()
pour fermer un descripteur de socket, mais lorsque vous utilisez la fonction select()
Je travaille avec des fd_set et je ne sais pas vraiment quoi faire pour les fermer. Ou bien, existe-t-il un moyen de limiter le nombre de descripteurs de socket dans un ensemble ? J'ai trouvé la macro FD_SETSIZE, mais je n'ai pas réussi à la faire fonctionner et je ne suis même pas sûr qu'elle règle le problème.
Merci pour votre temps !