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.

3 réponses

5 6 7 8 9
Avatar
Thomas Nemeth
Laurent Wacrenier a tapoté :

Thomas Nemeth écrit:
Visiblement je ne reçois pas (ou n'émet pas) les paquets de données,
devrais-je utiliser connect() sur le récepteur au lieu de simplement
bind() ?


Utilise tcpdump pour voir ce qui circule sur le réseau et analyse les
code de retour des fonctions (if (sendto() == -1) { perror("sendto");},
etc.)


Les données sont bien émises : elles passent dans tcpdump sur une
machine cliente. C'est recvfrom qui ne reçoit rien. Extrait du code
client :

sock = socket(PF_INET, SOCK_DGRAM, 0);
option = 1;
res = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &option, sizeof(int));
[...]
memset(&local, 0, sizeof(struct sockaddr_in));
local.sin_family = PF_INET;
local.sin_port = htons(port);
inet_aton(adresse_locale, &(local.sin_addr));
res = bind(sock, (struct sockaddr *) &local, sizeof(struct sockaddr_in));
[...]
while (cont = TRUE)
{
struct sockaddr_in from;
socklen_t len;
memset(&from, 0, sizeof(struct sockaddr_in));
ret_size = recvfrom(fd, buffer, size, 0,
(struct sockaddr *)&from, &len);
/* - Extraire les données
* - Les afficher
*/
[...]
}

recvfrom() étant bloquant, le programme s'arrête sur lui et rien n'est
reçu. Pourtant tcpdump me montre tout...


Thomas.


Avatar
DINH Viêt Hoà

recvfrom() étant bloquant, le programme s'arrête sur lui et rien n'est
reçu. Pourtant tcpdump me montre tout...


ssize_t
recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from,
socklen_t *fromlen);

If from is non-nil, and the socket is not connection-oriented, the source
address of the message is filled in. Fromlen is a value-result parame-
ter, initialized to the size of the buffer associated with from, and mod-
ified on return to indicate the actual size of the address stored there.

en résumé, fromlen doit avoir une valeur initiale intéressante.

--
DINH V. Hoa,

"écrire 'dsl' au lieu de 'désolé', c'est pas un problème d'orthographe,
c'est un problème de capillarité palmaire" -- ed

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


recvfrom() étant bloquant, le programme s'arrête sur lui et rien
n'est reçu. Pourtant tcpdump me montre tout...


ssize_t
recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr
*from,
socklen_t *fromlen);
[...]

en résumé, fromlen doit avoir une valeur initiale intéressante.


Effectivement, malheureusement en lui donnant une valeur initiale ça ne
change rien...

Thomas.


5 6 7 8 9