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.
Maintenant il faudrait que j'étudie la possibilité de faire en sorte que l'un des clients puisse contacter le serveur afin de le faire changer de mode de fonctionnement. Je pense qu'un select dans un autre thread permettrait de se mettre en attente de lecture...
Pas besoin de select() s'il y a des threads. Il suffit de bloquer sur recvfrom() avec une socket de controle sur un autre port.
Si si : dans ce thread j'attend aussi des connexions sur RS :)
Thomas.
Laurent Wacrenier a tapoté :
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
Maintenant il faudrait que j'étudie la possibilité de faire en
sorte que l'un des clients puisse contacter le serveur afin de le
faire changer de mode de fonctionnement. Je pense qu'un select
dans un autre thread permettrait de se mettre en attente de
lecture...
Pas besoin de select() s'il y a des threads. Il suffit de bloquer sur
recvfrom() avec une socket de controle sur un autre port.
Si si : dans ce thread j'attend aussi des connexions sur RS :)
Maintenant il faudrait que j'étudie la possibilité de faire en sorte que l'un des clients puisse contacter le serveur afin de le faire changer de mode de fonctionnement. Je pense qu'un select dans un autre thread permettrait de se mettre en attente de lecture...
Pas besoin de select() s'il y a des threads. Il suffit de bloquer sur recvfrom() avec une socket de controle sur un autre port.
Si si : dans ce thread j'attend aussi des connexions sur RS :)
Thomas.
Laurent Wacrenier
Thomas Nemeth écrit:
Après avoir fouillé les différentes pages man j'ai des difficultés à saisir la façon de se servir de bind() et connect(). Pour socket(), accept(), (set|get)sockopt(), send[to](), recv[from](), je vois bien mais l'utilité de bind() et connect() ne me semble pas claire (bien qu'indispensable) et je les utilise donc de façon robotique sans trop comprendre les mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça ne sert qu'en mode connecté (TCP).
accept() reçoit les demandes de connexion.
bind() associe une adresse à une socket. Il faut l'utiliser avant connect() pour avoir où on se connecte ou accept() pour savoir sur quoi on attend.
Avant accept() (et après bind()), il faut aussi faire un listen() pour parametrer la queue d'acceptation de connexion.
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
Après avoir fouillé les différentes pages man j'ai des difficultés à
saisir la façon de se servir de bind() et connect(). Pour socket(),
accept(), (set|get)sockopt(), send[to](), recv[from](), je vois bien
mais l'utilité de bind() et connect() ne me semble pas claire (bien
qu'indispensable) et je les utilise donc de façon robotique sans
trop comprendre les mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça
ne sert qu'en mode connecté (TCP).
accept() reçoit les demandes de connexion.
bind() associe une adresse à une socket.
Il faut l'utiliser avant connect() pour avoir où on se connecte ou
accept() pour savoir sur quoi on attend.
Avant accept() (et après bind()), il faut aussi faire un listen()
pour parametrer la queue d'acceptation de connexion.
Après avoir fouillé les différentes pages man j'ai des difficultés à saisir la façon de se servir de bind() et connect(). Pour socket(), accept(), (set|get)sockopt(), send[to](), recv[from](), je vois bien mais l'utilité de bind() et connect() ne me semble pas claire (bien qu'indispensable) et je les utilise donc de façon robotique sans trop comprendre les mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça ne sert qu'en mode connecté (TCP).
accept() reçoit les demandes de connexion.
bind() associe une adresse à une socket. Il faut l'utiliser avant connect() pour avoir où on se connecte ou accept() pour savoir sur quoi on attend.
Avant accept() (et après bind()), il faut aussi faire un listen() pour parametrer la queue d'acceptation de connexion.
Thomas Nemeth
Christophe Blaess a tapoté :
avec UDP, tu utilises sendto() pour donner les port/addresse destination.
Groumph :( Pas possible de faire un bind() suivi de plusieurs send() dans ce cas ?
Il est possible d'utiliser connect() sur une socket UDP (en donnant l'adresse d'un correspondant). Dans ce cas
Sauf que... Dans ce cas c'est du broadcast (du moins pour la partie que je décrivais) et que je ne connais pas les correspondants.
Thomas.
Christophe Blaess a tapoté :
avec UDP, tu utilises sendto() pour donner les port/addresse
destination.
Groumph :(
Pas possible de faire un bind() suivi de plusieurs send() dans ce
cas ?
Il est possible d'utiliser connect() sur une socket UDP
(en donnant l'adresse d'un correspondant). Dans ce cas
Sauf que... Dans ce cas c'est du broadcast (du moins pour la partie
que je décrivais) et que je ne connais pas les correspondants.
avec UDP, tu utilises sendto() pour donner les port/addresse destination.
Groumph :( Pas possible de faire un bind() suivi de plusieurs send() dans ce cas ?
Il est possible d'utiliser connect() sur une socket UDP (en donnant l'adresse d'un correspondant). Dans ce cas
Sauf que... Dans ce cas c'est du broadcast (du moins pour la partie que je décrivais) et que je ne connais pas les correspondants.
Thomas.
Laurent Wacrenier
Thomas Nemeth écrit:
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser send() et non sendto() (puisque bind "affecte un <<nom>> à une socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne peut pas.
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser
send() et non sendto() (puisque bind "affecte un <<nom>> à une
socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne
peut pas.
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser send() et non sendto() (puisque bind "affecte un <<nom>> à une socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne peut pas.
Thomas Nemeth
Laurent Wacrenier a tapoté :
Thomas Nemeth écrit:
Après avoir fouillé les différentes pages man j'ai des difficultés à saisir la façon de se servir de bind() et connect(). Pour socket(), accept(), (set|get)sockopt(), send[to](), recv[from](), je vois bien mais l'utilité de bind() et connect() ne me semble pas claire (bien qu'indispensable) et je les utilise donc de façon robotique sans trop comprendre les mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça ne sert qu'en mode connecté (TCP).
bind() associe une adresse à une socket. Il faut l'utiliser avant connect() pour avoir où on se connecte ou accept() pour savoir sur quoi on attend.
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). 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.
Thomas.
Laurent Wacrenier a tapoté :
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
Après avoir fouillé les différentes pages man j'ai des
difficultés à saisir la façon de se servir de bind() et
connect(). Pour socket(), accept(), (set|get)sockopt(),
send[to](), recv[from](), je vois bien mais l'utilité de bind()
et connect() ne me semble pas claire (bien qu'indispensable) et
je les utilise donc de façon robotique sans trop comprendre les
mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça
ne sert qu'en mode connecté (TCP).
bind() associe une adresse à une socket.
Il faut l'utiliser avant connect() pour avoir où on se connecte ou
accept() pour savoir sur quoi on attend.
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).
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.
Après avoir fouillé les différentes pages man j'ai des difficultés à saisir la façon de se servir de bind() et connect(). Pour socket(), accept(), (set|get)sockopt(), send[to](), recv[from](), je vois bien mais l'utilité de bind() et connect() ne me semble pas claire (bien qu'indispensable) et je les utilise donc de façon robotique sans trop comprendre les mécanismes sous-jacents.
connect() envoie une demande de connexion. Comme son nom l'indique, ça ne sert qu'en mode connecté (TCP).
bind() associe une adresse à une socket. Il faut l'utiliser avant connect() pour avoir où on se connecte ou accept() pour savoir sur quoi on attend.
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). 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.
Thomas.
Laurent Wacrenier
Thomas Nemeth écrit:
- clients : reçoivent en permanence ces données. socket() setsockopt() while (cond) recvfrom()
Il manque un bind() pour définir l'adresse et le port d'attente.
Mais si je veux pouvoir faire en sorte qu'un des clients envoie une commande de changement de type de données au serveur, il faut que le serveur puisse écouter... Or écouter sur du broadcast alors qu'on y écrit soi-même peut être un poil gênant, non ? Le serveur risque de recevoir ses propres messages et donc croire qu'il reçoit une demande de connexion.
Mieux vaut utiliser un autre port pour le controle.
Le fait que les autres clients recoivent la commande n'est pas un pb puisqu'ils pourront faire un traitement discriminatif sur les données reçues.
Y aurait-il la possibilité pour le serveur de faire un truc dans le genre : socket() setsockopt() bind() // sur l'adresse locale recv() // dans un thread
recvfrom()
while (cont) sendto(broadcast) // dans un autre thread
Plutôt sendto() vers l'adresse récupérée par le recvfrom().
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
- clients : reçoivent en permanence ces données.
socket()
setsockopt()
while (cond) recvfrom()
Il manque un bind() pour définir l'adresse et le port d'attente.
Mais si je veux pouvoir faire en sorte qu'un des clients envoie une
commande de changement de type de données au serveur, il faut que le
serveur puisse écouter... Or écouter sur du broadcast alors qu'on y
écrit soi-même peut être un poil gênant, non ? Le serveur risque de
recevoir ses propres messages et donc croire qu'il reçoit une
demande de connexion.
Mieux vaut utiliser un autre port pour le controle.
Le fait que les autres clients recoivent la commande n'est pas un pb
puisqu'ils pourront faire un traitement discriminatif sur les
données reçues.
Y aurait-il la possibilité pour le serveur de faire un truc dans le
genre :
socket()
setsockopt()
bind() // sur l'adresse locale
recv() // dans un thread
recvfrom()
while (cont) sendto(broadcast) // dans un autre thread
Plutôt sendto() vers l'adresse récupérée par le recvfrom().
- clients : reçoivent en permanence ces données. socket() setsockopt() while (cond) recvfrom()
Il manque un bind() pour définir l'adresse et le port d'attente.
Mais si je veux pouvoir faire en sorte qu'un des clients envoie une commande de changement de type de données au serveur, il faut que le serveur puisse écouter... Or écouter sur du broadcast alors qu'on y écrit soi-même peut être un poil gênant, non ? Le serveur risque de recevoir ses propres messages et donc croire qu'il reçoit une demande de connexion.
Mieux vaut utiliser un autre port pour le controle.
Le fait que les autres clients recoivent la commande n'est pas un pb puisqu'ils pourront faire un traitement discriminatif sur les données reçues.
Y aurait-il la possibilité pour le serveur de faire un truc dans le genre : socket() setsockopt() bind() // sur l'adresse locale recv() // dans un thread
recvfrom()
while (cont) sendto(broadcast) // dans un autre thread
Plutôt sendto() vers l'adresse récupérée par le recvfrom().
Thomas Nemeth
Laurent Wacrenier a tapoté :
Thomas Nemeth écrit:
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser send() et non sendto() (puisque bind "affecte un <<nom>> à une socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne peut pas.
Bon, ok, tant pis...
Merci pour tout, en tout cas, vous m'avez tous bien aidé !
Thomas.
Laurent Wacrenier a tapoté :
Thomas Nemeth <thomas.nemeth@betatech.invalid> écrit:
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser
send() et non sendto() (puisque bind "affecte un <<nom>> à une
socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne
peut pas.
Bon, ok, tant pis...
Merci pour tout, en tout cas, vous m'avez tous bien aidé !
Ce qui me pose pb c'est : est-ce que bind() permet d'utiliser send() et non sendto() (puisque bind "affecte un <<nom>> à une socket" mais la page man ne parle pas de <<connexion>>) ?
Il aurait pu, ne serait-ce que par homogénéité avec recv(), mais il ne peut pas.
Bon, ok, tant pis...
Merci pour tout, en tout cas, vous m'avez tous bien aidé !
Thomas.
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.
Christophe Blaess <pas@de.reponse> écrit:
Il est possible d'utiliser connect() sur une socket UDP
(en donnant l'adresse d'un correspondant).
Il est possible d'utiliser connect() sur une socket UDP (en donnant l'adresse d'un correspondant).
Pas dans l'univers connu.
Laurent Wacrenier
Nicolas George <nicolas$ écrit:
En UDP, connect est possible également : il revient à fixer une destination implicite pour les paquets envoyés avec send tout court, et à ignorer les paquets qui ne viennent pas de l'adresse correspondante.
S'il n'y a qu'une seule adresse, ça se règle avec un bind().
Nicolas George <nicolas$george@salle-s.org> écrit:
En UDP, connect est possible également : il revient à fixer une destination
implicite pour les paquets envoyés avec send tout court, et à ignorer les
paquets qui ne viennent pas de l'adresse correspondante.
S'il n'y a qu'une seule adresse, ça se règle avec un bind().
En UDP, connect est possible également : il revient à fixer une destination implicite pour les paquets envoyés avec send tout court, et à ignorer les paquets qui ne viennent pas de l'adresse correspondante.
S'il n'y a qu'une seule adresse, ça se règle avec un bind().