Pourquoi FD_SET / FD_ZERO pour select () dans la boucle?

J’utilise la fonction select pour la communication entre mes sockets. J’ai une boucle while et je fais –

while(!done) { FD_ZERO(&read_flags); FD_ZERO(&write_flags); FD_SET(comm_fd1, &read_flags); FD_SET(comm_fd2, &read_flags); FD_SET(STDIN_FILENO, &read_flags); FD_SET(comm_fd1, &write_flags); FD_SET(comm_fd2, &write_flags); FD_SET(STDIN_FILENO, &write_flags); //call select sel = select(comm_fd1+comm_fd2+1, &read_flags, &write_flags, (fd_set*)0, &waitd); 

et la même chose avec différentes variables du côté client. J’ai obtenu cette technique de base à partir d’un tutoriel en ligne et je viens de l’accompagner. Ensuite, il m’a frappé. Pourquoi effacer l’ensemble et append des descripteurs de fichier à chaque boucle? S’ils sont déjà ajoutés, pourquoi les effacer et les append à nouveau? J’ai donc essayé de ne le faire qu’une fois avant, et le code ne fonctionne plus de la même façon. Quelqu’un peut-il expliquer pourquoi? Est-ce simplement parce que select modifie le contenu de l’ensemble? Toute aide et / ou compréhension est appréciée.

Lorsque select renvoie, il a mis à jour les ensembles pour indiquer quels descripteurs de fichier sont prêts pour la lecture / écriture / exception. Tous les autres drapeaux ont été effacés.

Il est important de réactiver les descripteurs de fichier qui ont été effacés avant de lancer une autre sélection, sinon vous ne serez plus en attente de ces descripteurs de fichier.

En ce qui concerne le ré-effacement, cela peut être une bonne habitude à adopter, car si vous devez modifier l’ensemble des descripteurs de fichier (par exemple, l’ajout d’un socket nouvellement ouvert à l’ensemble de lecture), vous devrez l’effacer et le reconstruire. à chaque fois, afin que ce soit correct lorsque l’état du programme change.

Est-ce simplement parce que select modifie le contenu de l’ensemble?

Oui, après select retours select , seuls les descripteurs prêts sont laissés dans les ensembles.