OVH Cloud OVH Cloud

Socket UDP en broadcast

83 réponses
Avatar
Thomas Nemeth
Bonjour !

Je cherche à émettre des données (une chaîne de 30 caractères) en
broadcast UDP. Si je sais me débrouiller pour les socket TCP (et encore
je n'ai pas tenté le broadcast), pour les sockets UDP j'ai du mal à voir
comment configurer la socket afin de pouvoir écrire à partir d'une
machine et lire à partir de plusieurs autres.

Jusque-là, pour mes serveurs, je faisais la recette habituelle :
- pour les serveurs :
socket()
setsockopt() pour REUSEADDR et LINGER
bind()
listen()

- pour les clients :
socket()
setsockopt() (idem)
bind()
connect()

Or pour les sockets UDP en broadcast, je ne vois pas trop comment
faire. Pour l'instant (ce qui ne marche pas) :
socket()
setsockopt() pour REUSEADDR et BROADCAST
connect()

Puis write() ou send() pour écrire et read() ou recv() pour lire.

Quelqu'un a-t-il une idée sur la méthode à appliquer ?
Merci d'avance.

Thomas.

10 réponses

Avatar
DINH Viêt Hoà

Oui. C'est ce que j'ai trouvé dans les docs en ligne par la suite
et ce que m'a dit Viêt Hoà (si c'est comme ça que je dois l'écrire).


"Hoà".

Comme je l'ai écrit précédemment, ce qui est étrange c'est que
bind() permette d'associer un adresse et un port à une socket mais
qu'on ne peut(pourrait) pas utiliser send() par la suite.


pour communiquer, tu as besoin d'une adresse et port local et une
adresse et port distant.

avec bind(), tu règles l'adresse et port local.

connect() ou sendto() règle l'adresse et port distant.

--
DINH V. Hoa,

"Je suis une merde" -- jyb

Avatar
Thomas Nemeth
DINH Viêt Hoà a tapoté :


Oui. C'est ce que j'ai trouvé dans les docs en ligne par la suite
et ce que m'a dit Viêt Hoà (si c'est comme ça que je dois
l'écrire).


"Hoà".


Ok :)


Comme je l'ai écrit précédemment, ce qui est étrange c'est que
bind() permette d'associer un adresse et un port à une socket
mais qu'on ne peut(pourrait) pas utiliser send() par la suite.


pour communiquer, tu as besoin d'une adresse et port local et une
adresse et port distant.

avec bind(), tu règles l'adresse et port local.


Pour être plus précis, d'après ce que j'ai compris, bind() permet
d'informer l'OS sous-jacent que notre programme peut se placer en
écoute sur cette adresse et doit, par conséquent, recevoir les
paquets qui y sont envoyés.


connect() ou sendto() règle l'adresse et port distant.


Idem avec recvfrom d'après ce que j'ai lu et compris.


Thomas.


Avatar
Christophe Blaess
Christophe Blaess écrit:

Il est possible d'utiliser connect() sur une socket UDP
(en donnant l'adresse d'un correspondant).



Pas dans l'univers connu.


Ben si. Dans celui de la norme SUSv3 en tout cas :

<http://www.opengroup.org/onlinepubs/009695399/functions/connect.html>

extrait :

"For SOCK_DGRAM sockets, the peer address identifies where all
datagrams are sent on subsequent send() functions, and limits
the remote sender for subsequent recv() functions."



--
Christophe Blaess
http://www.blaess.fr/christophe/


Avatar
Thomas Nemeth
Nicolas George a tapoté :

Laurent Wacrenier wrote in message
:
S'il n'y a qu'une seule adresse, ça se règle avec un bind().


bind, ça règle l'adresse locale, ça n'a rien à voir. Au vu de quelques
autres messages, une petite révision de la doc de connect s'impose :

« If the initiating socket is not connection-mode, then connect()
shall set the socket's peer address, and no connection is made.


Hum... Ce qui est mon cas.


For
SOCK_DGRAM sockets, the peer address identifies where all datagrams
are sent on subsequent send() functions, and limits the remote sender
for subsequent recv() functions.


C'est ce qui m'avait fait mettre connect() en premier lieu...
Remarque avec simplement :
socket()
setsockopt()
while (cond) sendto(broadcast)
d'un côté et :
socket()
setsockopt()
bind(broadcast)
while (cond) recvfrom()
de l'autre côté, ça ne marche pas mieux :(


Thomas.


Avatar
DINH Viêt Hoà

Comme je l'ai écrit précédemment, ce qui est étrange c'est que
bind() permette d'associer un adresse et un port à une socket
mais qu'on ne peut(pourrait) pas utiliser send() par la suite.


pour communiquer, tu as besoin d'une adresse et port local et une
adresse et port distant.

avec bind(), tu règles l'adresse et port local.


Pour être plus précis, d'après ce que j'ai compris, bind() permet
d'informer l'OS sous-jacent que notre programme peut se placer en
écoute sur cette adresse et doit, par conséquent, recevoir les
paquets qui y sont envoyés.


alors, tu n'as pas compris :)

en UDP/IP ou TCP/IP, lorsque tu envoies un paquet, il est décoré avec
les champs suivant :
adresse source, port source, adresse destination, port destination

netstat permet d'afficher ce genre d'information.
Exemple avec TCP :

tcp 0 0 82.228.130.119:42721 212.27.42.24:143 ESTABLISHED

82.228.130.119 est l'adresse IP à partir de laquelle on va contacter le
serveur. 42721 est le port utilisé pour le contacter (il est souvent
pris au hasard (dans le sens "quelconque")). On parle souvent peu de ce
port car il n'a pas souvent besoin d'avoir une valeur fixée.

212.27.42.24 est l'adresse IP qu'on va contacter. 143 est le port
que l'on contacte. C'est le port sur lequel le serveur écoute.

212.27.42.24 fait tourner un serveur IMAP.

82.228.130.119 est le client IMAP.

--
DINH V. Hoa,

"Je suis une merde" -- jyb



Avatar
Laurent Wacrenier
Christophe Blaess écrit:
Il est possible d'utiliser connect() sur une socket UDP
(en donnant l'adresse d'un correspondant).



Pas dans l'univers connu.


Ben si. Dans celui de la norme SUSv3 en tout cas :


Effectivement. ça ne m'était pas venu à l'idée d'utiliser connect() en
monde non connecté. Un nouveau monde s'offre à moi.



Avatar
Thomas Nemeth
DINH Viêt Hoà a tapoté :


Comme je l'ai écrit précédemment, ce qui est étrange c'est que
bind() permette d'associer un adresse et un port à une socket
mais qu'on ne peut(pourrait) pas utiliser send() par la suite.


pour communiquer, tu as besoin d'une adresse et port local et une
adresse et port distant.

avec bind(), tu règles l'adresse et port local.


Pour être plus précis, d'après ce que j'ai compris, bind() permet
d'informer l'OS sous-jacent que notre programme peut se placer en
écoute sur cette adresse et doit, par conséquent, recevoir les
paquets qui y sont envoyés.


alors, tu n'as pas compris :)


Ah ?


en UDP/IP ou TCP/IP, lorsque tu envoies un paquet, il est décoré avec
les champs suivant :
adresse source, port source, adresse destination, port destination


Oui.

[snip : je connais depuis belle lurette]

Tu veux dire que bind() ne fait _que_ positionner l'adresse et le
port local pour les paquets entrants/sortants ?
Quel(s) mécanisme(s) au sein de l'OS met-il en jeu alors exactement
et à quoi sert-il ?
Juste à dire "positionner l'adresse et le port à X e Y" et puis
basta ?
Lors d'une réception ça servirait à quoi sinon à dire à l'OS qu'on
attend des paquet sur telle adresse/tel port ?
Si ce n'est pas ça, comment se fait-il qu'on ne reçoive alors pas
tous les paquets arrivant sur la machine et en y mettant, au moment
de la réception par le programme, l'adresse et le port ?


Thomas.




Avatar
Laurent Wacrenier
Thomas Nemeth écrit:
Tu veux dire que bind() ne fait _que_ positionner l'adresse et le
port local pour les paquets entrants/sortants ?
Quel(s) mécanisme(s) au sein de l'OS met-il en jeu alors exactement
et à quoi sert-il ?


Ça reserve le couple adresse/port pour la socket et évite que
quelqu'un d'autre ne le chipe.

Avatar
DINH Viêt Hoà

Tu veux dire que bind() ne fait _que_ positionner l'adresse et le
port local pour les paquets entrants/sortants ?
Quel(s) mécanisme(s) au sein de l'OS met-il en jeu alors exactement
et à quoi sert-il ?
Juste à dire "positionner l'adresse et le port à X e Y" et puis
basta ?
Lors d'une réception ça servirait à quoi sinon à dire à l'OS qu'on
attend des paquet sur telle adresse/tel port ?
Si ce n'est pas ça, comment se fait-il qu'on ne reçoive alors pas
tous les paquets arrivant sur la machine et en y mettant, au moment
de la réception par le programme, l'adresse et le port ?


en tout cas, bonne question à laquelle Laurent a répondu.
que se passe-t-il d'ailleurs si tu ne bindes pas le socket ?
reçois-tu les messages quand même ?
J'ai l'impression qu'on est obligé de binder pour au moins indiquer sur
quelle adresse IP on souhaite recevoir les paquets.

bind(), dans ce cas-là, ne sert-il pas à filtrer simplement les paquets
reçus pour donner les bons à l'application.

--
DINH V. Hoa,

"Je suis une merde" -- jyb

Avatar
Thomas Nemeth
Laurent Wacrenier a tapoté :

Thomas Nemeth écrit:
Tu veux dire que bind() ne fait _que_ positionner l'adresse et le
port local pour les paquets entrants/sortants ?
Quel(s) mécanisme(s) au sein de l'OS met-il en jeu alors
exactement et à quoi sert-il ?


Ça reserve le couple adresse/port pour la socket et évite que
quelqu'un d'autre ne le chipe.


D'accord.
J'en étais à penser qu'il fallait que j'utilise bind sur
l'émetteur... Visiblement ce n'est donc pas le cas.


Thomas.