[Résolu] Problème de compilation fonction poll()

Problème de compilation fonction poll() [Résolu] - C - Programmation

Marsh Posté le 29-05-2006 à 12:58:31    

Bonjour,
 
J'utilise Dev-C++ 4.9.9.2 sous Windows XP, le compilateur est MinGW.
 
Mon but est d'utiliser poll() pour appliquer un timeout à une commande recvfrom().
 
 
 
D'après mes recherches, il existe select() à laquelle je ne comprends
rien, et poll() qui semble plus simple surtout avec des exemples.
 
 
 
(je me base sur http://hyatus.newffr.com/TAZ/Reseaux/prog_reseau1.html pour l'utilisation de poll() )
 
 
Et donc voici mon code :
 

Code :
  1. #include <winsock2.h>
  2. #include <sys/poll.h>
  3. #include "d:\Dev-Cpp\include\c++\3.4.2\cstdio"
  4. #define bzero(ptr,size) memset (ptr, 0, size);
  5. (bla bla bla...)
  6.     struct pollfd fds;
  7.     bzero(&fds, sizeof fds);
  8.     fds.events = POLLRDNORM;
  9.     fds.fd = id_de_la_socket;
  10. // jusqu'ici ça se compile bien
  11.     if(poll(&fds, 1, 2000) > 0)
  12.        {
  13.             blablabla...
  14.         }


 
Mon problème est qu'à la compilation, j'ai l'erreur suivante :
 
 
  [Linker error] undefined reference to `poll'
 
 
Bigre.
 
J'ai déjà du récupérer manuellement un poll.h qui n'était pas fourni avec Dev-C++, mais visiblement il lui manque encore un truc. (ou peut être que le poll.h récupéré n'est pas le bon pour MinGW).
 
Est-ce que poll() est implémentée dans mon environnement ?
 
Sinon, au pire, quelqu'un aurait-il un exemple clair et simple de la fonction select() si je suis obligé de passer par ça ?
 
Merci d'avance,
 
Arnaud

Message cité 1 fois
Message édité par vilcocoy le 30-05-2006 à 08:30:01
Reply

Marsh Posté le 29-05-2006 à 12:58:31   

Reply

Marsh Posté le 29-05-2006 à 13:04:29    

D'après cette page :
http://www.schweikhardt.net/identifiers.html
 
La fonction poll() est POSIX.2, ce qui signifie que tu la trouveras dans tous les unixoïdes récents, mais pas obligatoirement sur d'autres systèmes d'exploitation.
Windows a bien avancé la compatibilité avec POSIX.1, je ne sais pas où ils en sont de POSIX.2
 
Pour une bonne documentation sur les fonctions C, quel que soit l'OS sur lequel on est, une astuce connue est d'effectuer une recherche sur "man fonction_à_chercher" dans ton moteur de recherche préféré.
 
Ainsi :
 
select() = http://www.hmug.org/man/2/select.php
et
poll() = http://www.hmug.org/man/2/poll.php
 
:)


Message édité par Elmoricq le 29-05-2006 à 13:09:29
Reply

Marsh Posté le 29-05-2006 à 13:17:21    

Merci Elmoricq,
 
J'avais déjà trouvé les pages de man que tu me proposes, mais celle de select() est vraiment trop gratinée pour mon niveau de débutant total en C.
 
C'est dommage, le poll() me convenait parfaitement.
 
Bon, je vais essayer d'y comprendre quelque chose à select()... mais si de bonnes âmes ont pitié, elles sont les bienvenues !

Reply

Marsh Posté le 29-05-2006 à 15:31:42    

vilcocoy a écrit :

Bonjour,
 
J'utilise Dev-C++ 4.9.9.2 sous Windows XP, le compilateur est MinGW.
 
...
 
J'ai déjà du récupérer manuellement un poll.h qui n'était pas fourni avec Dev-C++, mais visiblement il lui manque encore un truc. (ou peut être que le poll.h récupéré n'est pas le bon pour MinGW).


 
Bah c'est pas en récupérant un fichier d'en-tête que ça va marcher. Il faut que la fonction soit définie dans un fichier .c ou une bibliothèque (style libc). Le fichier d'en-tête déclare juste la fonction.

Reply

Marsh Posté le 29-05-2006 à 15:38:35    

Code :
  1. struct timeval timeout;
  2.   timeout.tv_sec = 1; ; timeout de 1 seconde
  3.   timeout.tv_usec =0;
  4.   fd_set fds;
  5.   FD_ZERO(&fds);
  6.   FD_SET(id_de_la_socket,&fds);
  7.   int rc=0;
  8.   rc = select(id_de_la_socket+1,NULL,&fds,NULL,&timeout);
  9.   if (!(FD_ISSET(STDIN, &fds)))
  10.       fprintf(stdout,"Erreur, impossible d'ouvrir
  11.                le port socket : %s\n",strerror(errno));
  12.       return -1;
  13.     }

Reply

Marsh Posté le 29-05-2006 à 16:09:57    

Merci Karlkox,
 
Par contre il ne connait pas STDIN, qu'est ce qui me manque ?

Reply

Marsh Posté le 29-05-2006 à 16:17:39    

Je pense qu'il s'agit de STDIN_FILENO, définit dans unistd.h

Message cité 1 fois
Message édité par Elmoricq le 29-05-2006 à 16:17:59
Reply

Marsh Posté le 29-05-2006 à 16:23:44    

... marche pô  :(  
 
en fait il n'attend pas le timeout et me rend la main aussitôt en affichant le msg d'erreur.
 
Pourtant je suis sûr qu'un datagramme UDP arrive puisque je l'émets, et je le vois en sniffant la carte.
 
Si j'affiche rc, il est égal à 1.
 
 
 

Elmoricq a écrit :

Je pense qu'il s'agit de STDIN_FILENO, définit dans unistd.h


Reply

Marsh Posté le 29-05-2006 à 16:33:53    

karlkox a écrit :

Code :
  1. rc = select(id_de_la_socket+1,NULL,&fds,NULL,&timeout);
  2.   if (!(FD_ISSET(STDIN, &fds)))



STDIN_FILENO
 
Sous Windows, select() ne fonctionne que sur le sockets. (Voir WaitForMultipleObjects() ou un bazar comme ça...)


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 29-05-2006 à 16:56:50    

Emmanuel Delahaye a écrit :

Sous Windows, select() ne fonctionne que sur le sockets.


 
Ca tombe bien, c'est justement les sockets que j'utilise !  ;)  
 
C'est vrai que STDIN_FILENO me surprenait un peu, mais dans mon désarroi j'ai essayé quand même...
 
Marche toujours pô  :cry:

Reply

Marsh Posté le 29-05-2006 à 16:56:50   

Reply

Marsh Posté le 29-05-2006 à 16:59:01    

Tu as inclu unistd.h ?

Reply

Marsh Posté le 29-05-2006 à 17:02:01    

Elmoricq a écrit :

Tu as inclu unistd.h ?


 
Oui, je l'ai inclus, mais apparement ça se réfère à une entrée fichier, moi je suis sur une socket réseau.
 
J'ai trouvé ce truc :

Code :
  1. if (FD_ISSET (id_de_la_socket , &fds)) blabla


 
que je vais tester de ce pas...

Reply

Marsh Posté le 29-05-2006 à 17:05:44    

Ah, je pensais que par "ça marche po", tu voulais dire que ça ne compilait pas.
Il faut être plus précis.

Reply

Marsh Posté le 29-05-2006 à 17:06:04    

... et qui marche pas non plus.
 
C'est quand même bizarre tout ça.

Reply

Marsh Posté le 29-05-2006 à 17:10:06    

Elmoricq a écrit :

Ah, je pensais que par "ça marche po", tu voulais dire que ça ne compilait pas.
Il faut être plus précis.


 
Oui excuse-moi, ça se compile, mais ça ne fait pas ce que je veux...
 
Le principe :
 
1. Emetteur -message-> recepteur
 
2. Emetteur passe en écoute avec mon select() et un rcvfrom()
 
3. Recepteur -accuséReception-> emetteur
 
-> mais mon emetteur ne capte jamais mon accusé de réception (une bête chaîne "ok" que je vois passer en sniff).
 
(note : par contre systématiquement mon emetteur envoie une réponse ICMP "host unreachable" après l'arrivée de l'accusé de réception, mais apparement c'est un bug windows connu, et ça ne devrait pas empêcher la récupération de l'accusé)

Reply

Marsh Posté le 29-05-2006 à 17:18:38    

Ha, je viens de découvrir un truc :
 
Si mon récepteur et mon emetteur tournent sur la meme machine, et que j'envoie sur 127.0.0.1, ça fonctionne.
 
Par contre, si j'envoie sur l'adresse ip réelle de la machine (toujours dans le cas ou emetteur et recepteur sont sur la même), ça ne marche plus.
 
Ca vous met sur une piste ?

Reply

Marsh Posté le 29-05-2006 à 17:25:31    

Bon, vous pouvez laisser tomber, je m'aperçois que le fonctionnement en loopback est aléatoire, mon truc est donc complètement foireux, je vais revoir ça à tête reposée.
 
Merci à ceux qui m'ont répondu.

Reply

Marsh Posté le 30-05-2006 à 08:29:08    

La nuit porte conseil... en voici la preuve :
 
Hier j'étais persuadé que mon récepteur ne captait pas ou ne traitait pas le message de mon emetteur.
 
Finalement, ce matin je me suis aperçu que le message de l'emetteur arrivait avant que mon recepteur n'ait eu le temps de se mettre en écoute !
 
Donc, voilà, une ptite tempo à coup de Sleep, et c'est réglé !
 
Merci !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed