xilebo noone | Bonjour,
J'ai un petit souci lors d'envoi de trame multicast sous linux. Voici un code exemple pour illustrer le problème :
Code :
- #include <stdio.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <string.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <errno.h>
- #include <arpa/inet.h>
- static const char multicast_group_sz[] = "224.1.2.3";
- static const short port = 65007;
- int main()
- {
- int sock = socket( AF_INET , SOCK_DGRAM , IPPROTO_UDP );
- unsigned long hote_l = inet_addr( multicast_group_sz );
- struct sockaddr_in addr;
- int ret;
- memset( &addr , 0 , sizeof(addr ));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = hote_l;
- addr.sin_port = htons( port );
- struct in_addr iface_addr;
- iface_addr.s_addr = inet_addr("172.17.17.17" );
- ret = setsockopt( sock , IPPROTO_IP , IP_MULTICAST_IF , (char *)&iface_addr , sizeof ( iface_addr ) );
- if ( ret < 0 )
- {
- printf("Error setsockopt %d\n", errno );
- }
- while ( 1 )
- {
- char buffer[1024];
- fgets( buffer, 1024 , stdin );
- int len = strlen( buffer);
- buffer[len - 1] = 0; // virer le \n et remplacer par un fin de chaine
- ret = sendto( sock , buffer , len , 0 ,(struct sockaddr *) &addr, sizeof ( addr ) );
- printf("sendto : %d %d\n" , ret , errno );
- if ( strcmp( buffer , "QUIT" ) == 0 )
- {
- break;
- }
- }
- close ( sock );
- return 0;
- }
|
si je commente les lignes
Code :
- struct in_addr iface_addr;
- iface_addr.s_addr = inet_addr("172.17.17.17" );
- ret = setsockopt( sock , IPPROTO_IP , IP_MULTICAST_IF , (char *)&iface_addr , sizeof ( iface_addr ) );
|
mon sendto renvoie une erreur. On va dire que c'est normal, je ne peux pas envoyer en multicast sur une socket, si je ne lui ai pas précisé préalablement qu'elle doit fonctionner en multicast.
Si maintenant je remplace ces mêmes lignes par :
Code :
- struct in_addr iface_addr;
- iface_addr.s_addr = INADDR_ANY;
- ret = setsockopt( sock , IPPROTO_IP , IP_MULTICAST_IF , (char *)&iface_addr , sizeof ( iface_addr ) );
|
setsockopt ne me retourne pas d'erreur ( donc on peut suppose que ca s'est bien passé ) , par contre mon sendto me renvoie également une erreur ( network unreachable me semble-t-il ).
Si maintenant je mets
Code :
- struct in_addr iface_addr;
- iface_addr.s_addr = inet_addr("172.17.17.17" );
- ret = setsockopt( sock , IPPROTO_IP , IP_MULTICAST_IF , (char *)&iface_addr , sizeof ( iface_addr ) );
|
Comme dans le code exemple, ici 172.17.17.17 étant l'adresse IP de l'interface sur laquelle je veux dialoguer ( eth0 ) , mon sendto fonctionne bien et je vois bien le paquet UDP partir avec wireshark.
Ma question est : pourquoi cela ne marche pas si je fais un setsockopt sur INADDR_ANY, y a-t-il une option supplémentaire pour autoriser ce genre de chose ?
Je précise que sous windows, ce code fonctionne bien, et c'est un besoin que j'ai car je ne connais pas forcément l'adresse IP de l'interface sur laquelle je veux dialoguer.
Merci d'avance |