broadcast UDP sous linux et UDP + connect - C - Programmation
Marsh Posté le 05-04-2012 à 09:21:41
J'en profite pour poser une 2ème question : l'UDP unicast ne fonctionne pas sous linux alors que le même code fonctionne sous windows.
A priori , c'est l'appel à la fonction connect qui fait échouer.
Voici les portions de code ( dialogue entre 2 machines : 172.17.0.163 le test unitaire sous linux , 172.17.0.160 le serveur qui réceptionne le test sous windows )
Initialisation de la socket
Code :
|
code faisant le send : Pas besoin de sendto, l'adresse par défaut est celle spécifiée dans le connect
Code :
|
code du receive :
Code :
|
Alors , avec ce code ( qui est le même sur les 2 machines ) voici comment sont fait les appels :
Sur la machine "test unitaire" je fais Init , puis Send, puis Recv , puis Shut.
Sur la machine "serveur pour test" , je fais Init , puis Recv , puis Send, puis Shut
Jusque là, c'est normal.
Avec ce code, si les 2 machines sont sous windows, mon test passe.
Avec ce même code, si la machine "test unitaire" est sous linux , et la machine "serveur pour test", le test ne passe pas.
Où est l'échec ?
- l'init fonctionne bien des 2 cotés ( les appels systèmes retournent tous OK ).
- le premier envoi sous linux se passe bien car il est bien recu sous windows. L'appel connect sous linux est donc cohérent puisque pour l'envoi, je fais un send, sans préciser le destinaire.
- suite à la réception sous windows, celui-ci envoie une réponse pour être réceptionné sous linux.
- c'est la réception sous linux qui pose problème, le select retourne "nodata", par conséquent, je ne peux pas faire le recv.
- A savoir que si je mets ( juste coté linux ) en commentaire l'appel à connect ( ce qui a pour conséquence de m'obliger à remplacer le send par un sendto vers ma machine "serveur pour test" , je ne change pas le recv , qui revient à faire un recvfrom avec sockaddr_in NULL ) , cela fonctionne bien.
Je ne comprends pas quelle erreur j'ai pu faire qui fait que le comportement est différent sous linux.
Il y a soit un appel de trop qui gêne ( dans les setsockopt par exemple ), soit il manque quelque chose spécifique à linux.
Avez vous une idée car je sèche ?
Merci
Marsh Posté le 04-04-2012 à 21:38:03
Bonsoir,
Je suis en train de coder une application nécessitant d'envoyer et de recevoir des broadcast sous linux et je rencontre quelques difficultés ( ou plutot interrogations ).
Je ne trouve pas de littérature sur internet m'expliquant en détail le fonctionnement, les pages man de chaque fonction sont insuffisantes à ce niveau.
Voici mon problème :
J'ai codé un petit test unitaire sous windows qui crée une socket DGRAM , et qui envoie en broadcast sur un port X des datas bien précis. Une application test ( sous windows egalement et uniquement ) se charge de réceptionner ces datas , et d'en renvoyer d'autre sur le même port X toujours en broadcast.
Ce test fonctionne sous windows, pour cela, j'ai juste eu besoin de créer ma socket ( DGRAM / IPPROTO_UDP ) , et de faire un bind sur l'adresse de l'interface sur laquelle je souhaite envoyer le broadcast. J'ai volontairement plusieurs interfaces, et ca envoie bien sur la 2eme ( vérifié sur wireshark des 2 cotés ).
Par contre, sous linux, le bind sur l'adresse de l'interface ne fonctionne pas. J'envoie bien mon message en broadcast, je vois bien qu'il part, qu'il est réceptionné par mon application test, celle-ci renvoie bien le message retour sur l'adresse broadcast, mais je ne le recois pas sous linux. Le seul moyen est de ne pas faire de bind sur l'adresse de l'interface comme sous windows, mais de le faire sur l'adresse broadcast.
Voici mes questions :
- Pourquoi cette différence, et où est-elle documentée ( je n'ai pas trouvé ) ? (je précise, j'ai bien fait le setsockopt qui positionne le broadcast à ACTIVE ).
- pourquoi quand je fais le bind cette fois-ci sur l'adresse d'interface cela ne fonctionne pas ?
- pourquoi quand je fais le bind sur la valeur INADDR_BROADCAST, cela ne fonctionne pas non plus ? Quelle différence avec l'adresse broadcast ( je vois bien la différence, INADDR_BROADCAST vaut 0xFFFFFFFF )
- pourquoi quand je fais le bind sur la valeur INADDR_ANY cela marche bien ?
Je ne peux pas poster de code ce soir, je ne suis pas à mon poste Je le ferai dès demain.
Merci de m'avoir lu
Message édité par xilebo le 05-04-2012 à 09:57:54