gestion des timeout sous Unix avec select() [C] - C - Programmation
Marsh Posté le 28-02-2004 à 13:43:21
va pour les fork, ca va claker comme solution...
nan serieux, le select c'est la vie, c'est pas compliqué :
avant de faire un recv (ou send), si on veut pas que l'appel soit bloquant, faut toujours faire un select avant, avec comme descripteur readfds (respectivement writefds) pour savoir si des données sont prêtes a être reçues (respectivement envoyées).
selon ce que select te retourne tu peux tranquillement appeler recv (ou send) sans que celui si ne bloque.
la gestion du timeout se fait avec le timeval passé au select.
(les descripteurs n'ont rien a voir avec des fichiers il me semble, enfin chuis pas expert SR non plus, quand tu parles de couche 3 je vois pas trop quoi ca etre)
Marsh Posté le 28-02-2004 à 14:14:15
Konar a écrit : va pour les fork, ca va claker comme solution... |
Ok, donc il faudrait utiliser le descripteur en lecture. Mais comment l'initaliser correctement ? Dans la page man il y a un exemple d'utilisation, avec des macros (genre FD_SET et FD_CLR) permettant de d'effacer des éléments. Alors j'ai testé cet exemple sur mon prog, mais apparemment l'initialisation du descripteur doit être mal faite, puisque le timeout s'écoule toujours. Il doit donc falloir utiliser autrement ces macros pour initialiser correctment, mais celles-ci ne sont dérites précisément nulle part. A moins que je ne l'ai pas vu (?).
Quand je parle de couche 3, c'est pour le modele OSI. Je me demandais si le soft qui décapsule le paquet IP, et en sort le datagramme UDP, ne modifierait pas un fichier.
Marsh Posté le 28-02-2004 à 15:03:39
un exemple :
Code :
|
fais gaffe aussi au timeval, le tv_sec est en secondes, mais le tv_usec est en micro-secondes, pas en milli-secondes, c'est souvent une source de confusion.
Marsh Posté le 28-02-2004 à 15:40:00
ok merci je vais essayer ça.
juste un truc, dans ton exemple : à quoi correspondent socket1 et socket2 ?
si moi je n'ai qu'un socket sur lequel je reçois , je peux faire juste un truc comme ça ? (si Socket est mon n° de socket, et en remplissant correctement la struct tv)
Code :
|
Marsh Posté le 28-02-2004 à 17:13:12
Socket1 et Socket2 correspondaient aux sockets a tester l'état.
si tu n'as qu'une seule socket, alors il n'y a qu'un seul FD_SET par descripteur.
de plus si tu veux uniquement recevoir des données, inutile d'utiliser un descripteur write.
Marsh Posté le 29-02-2004 à 10:43:29
alors j'ai testé un truc comme ça :
Code :
|
socketClient est mon n° de socket, et trameReception mon tableau dans lequel je stocke les données reçues.
et bien ça ne marche pas. Le timeout s'écoule à chaque fois. (J'ai laissé le descripteur en écriture 'au cas où')
où est l'erreur ?
Marsh Posté le 29-02-2004 à 17:12:50
détail : si le select retourne > 0, donc qu'une ou plusieurs sockets a déclenché le select, il faut tester chacun des descripteurs pour savoir quel est l'état (lecture, écriture, exception), et ce avec la macro FD_ISSET(Socket, descripteur).
par exemple dans ton code :
Code :
|
sinon ton code a l'air bon, je vois pas ce qui pourrait faire que ca marche pas. essaye plusieurs trucs genre virer les descripteurs en écriture et exception, regarde du coté du 1er paramètre du select (le man de ta machine dis quoi a son propos ?), et teste bien sans select pour voir si tu reçois bien des données...
sinon teste mieux le retour du select : 0 pour timeout, SOCKET_ERROR pour une erreur, ou un nb égal au nb de sockets prêtes et contenues dans les descripteurs.
Marsh Posté le 01-03-2004 à 18:19:08
merci pour tes conseils. Je n'ai pas réussi à le faire marcher, tant pis ... c'était pour un travail à rendre aujourd'hui. merci quand même.
Marsh Posté le 28-02-2004 à 10:40:27
bonjour,
je suis en train décrire un client TFTP avec de l'UDP sous Unix.
Jusque là mon client marche, mais sans gestion des timeout. C'est-à-dire que pour recevoir un datagramme du serveur, je fais un appel bloquant avec recvfrom(). J'aimerai donc mettre en place un timeout.
On m'a parlé de la fonction select(). Après étude de la page man correspondante, et qlq essais, je ne comprend pas bien quel type de descripteur pourrait être modifié (et donc sur quel descripteur select() pourrait scruter). Les 3 types de descripteurs (en lecture , ecriture et en cas d'exception) s'appliquent à des fichiers il me semble.
Donc :
* ou je ne connais pas vraiment Unix, et je devrais savoir que quand un datagramme est décapsulé de la couche 3, c'est un fichier qui est modifié.
* ou ... je ne sais pas comment faire (!)
Sinon si d'autres possibilités existent pour faire des timeout (à part y aller à coup de fork() et Cie) , je suis preneur. merci.