8
votes

pourquoi choisir () toujours renvoyer 0 après le premier délai d'attente

J'ai un problème de sélection de la fonction lorsque j'ai travaillé sur un programme de socket Linux. La page Select fonctionne bien comme la page de manuel indique si le client a connecté le côté serveur dans l'intervalle de temps configuré par le serveur. Si le délai d'attente est arrivé, la fonction Select reviendra 0 pour toujours. À ce moment-là, j'ai débogué le client et trouver le client connecté au serveur. Mais la fonction Select Retourne toujours 0. J'ai la recherche ce problème mais n'a trouvé aucune utile. Quelqu'un pourrait-il savoir pourquoi choisir comme ça? Ma version Linux est Rhel5.4. Merci pour votre aide.

Le code est illustré ci-dessous. xxx


2 commentaires

Conseil général: Utilisez le sondage () au lieu de sélectionner ().


Vous devez utiliser & tv au lieu de TV dans Sélectionnez


5 Réponses :



1
votes

Vous devez remplir votre FD_SET à chaque itération. La meilleure façon de le faire est de maintenir une collection de votre FDS quelque part et de mettre celui dont vous avez besoin pour l'appel sélectionné dans une FD_SET temporaire.

Si vous avez besoin de gérer beaucoup de clients, vous devrez peut-être modifier le FD_SetSize (dans /usr/include/sys/select.h ) macro.

Programmation de réseau heureuse :)


0 commentaires

3
votes

Vous avez déjà la bonne réponse - Re-Init the fd_set S avant chaque appel sur SELECT (2) . .

Je tiens à vous diriger vers une meilleure alternative - Linux fournit Epoll (4 ) installation. Bien que ce ne soit pas standard, il est beaucoup plus pratique puisque vous devez configurer les événements que vous n'attendez qu'une seule fois. Le noyau gère les tables d'événement descripteur de fichier pour vous, donc c'est beaucoup plus efficace. EPOLL fournit également fonctionnalité déclenché sur le bord , où seul un changement d'état sur un descripteur est signalé.

Pour complétude - BSDS fournit KQueue (2) < / Code> , Solaris a / dev / sondage .

Une dernière chose: votre code a une condition de course bien connue entre un client et le serveur. Jetez un coup d'œil à Stevens Unfl: Nonblocking Accepter .


2 commentaires

sondage est normalisé dans POSIX.


Mais ce n'est pas mieux que sélectionner .



4
votes

Le même effet semble se produire si vous ne réinitialisez pas la structure Timeval avant chaque appel de sélectionner.


1 commentaires

POSIX dit que la fonction SELECT () peut modifier le paramètre Timeout. Vraisemblablement, si vous êtes sur un système qui le modifie, sa valeur modifiée enregistre le temps qu'il reste jusqu'à ce que le délai d'expiration expire, ce qui soit zéro si le délai d'attente expirait et, par conséquent, après la première itération, l'appel dégénère dans un sondage parce que le Le délai d'attente zéro signifie «retour immédiatement» au lieu d'attendre si nécessaire ».



0
votes

J'ai le même problème dans mes codes similaires. J'ai suivi la suggestion d'effectuer une initialisation à chaque fois avant d'appeler Select () et cela fonctionne. Dans les codes dans ce cas, il suffit d'apporter les deux lignes en boucle le fera fonctionner.

FD_ZERO(&read_set);
FD_SET(servSock, &read_set);


0 commentaires