begin process at 2012 02 12 12:47:25
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Windows

 > 

Réseau & Internet

 > 

multicast en c sous windows


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

multicast en c sous windows

vendredi 15 février 2008 à 22:45:15 | multicast en c sous windows

tenrod

Bonsoir a tous,

voila j'ai un petit (voire un gros) pb avec le développement d'une application me permettant de faire du multicast en c sous windows.

J'ai récupéré le code suivant qui logiquement devrait fonctionner :

[code]
/*

multicast.c

- Mark Claypool, 2001

The following program sends or receives multicast packets. If invoked
with one argument, it sends a packet containing the current time to an
arbitrarily chosen multicast group and UDP port. If invoked with no
arguments, it receives and prints these packets. Start it as a sender on
just one host and as a receiver on all the other hosts.

*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <winsock2.h>

#define EXAMPLE_PORT 16000
#define EXAMPLE_GROUP "239.0.0.1"

main(int argc) {
   struct sockaddr_in addr;
   int addrlen, sock, cnt;
   struct ip_mreq mreq;
   char message[50];

   /* set up socket */
   sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) {
     perror("socket");
     exit(1);
   }
   bzero((char *)&addr, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
   addr.sin_port = htons(EXAMPLE_PORT);
   addrlen = sizeof(addr);

   if (argc > 1) {
    
      printf("I am a sender.  Sending time...\n");

      /* sender sends time every 3 seconds */
      addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
      while (1) {
     time_t t = time(0);    /* get current time */
     sprintf(message, "time is %-24.24s", ctime(&t)); /* make readable */
     printf("sending: %s\n", message);
     cnt = sendto(sock, message, sizeof(message), 0,
              (struct sockaddr *) &addr, addrlen);
     if (cnt < 0) {
         perror("sendto");
        exit(1);
     }
     sleep(3);
      }
   } else {

      printf("I am a receiver.  Waiting for messages...\n");

      /* receiver plays out messages */
      if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {       
         perror("bind");
     exit(1);
      }   
      mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);        
      mreq.imr_interface.s_addr = htonl(INADDR_ANY);        
      if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
             &mreq, sizeof(mreq)) < 0) {
     perror("setsockopt mreq");
     exit(1);
      }        
      while (1) {
      cnt = recvfrom(sock, message, sizeof(message), 0,
            (struct sockaddr *) &addr, &addrlen);
     if (cnt < 0) {
        perror("recvfrom");
        exit(1);
     } else if (cnt == 0) {
         break;
     }
     printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
        }
    }
}
[\code]

Mais voila à la compilation c'est le drame :
[code]
c:\documents and settings\administrateur\bureau\toto.c(9) : fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory
c:\documents and settings\administrateur\bureau\toto.c(12) : fatal error C1083: Cannot open include file: 'netinet/in.h': No such file or directory
c:\documents and settings\administrateur\bureau\toto.c(13) : fatal error C1083: Cannot open include file: 'arpa/inet.h': No such file or directory
c:\documents and settings\administrateur\bureau\toto.c(14) : fatal error C1083: Cannot open include file: 'netdb.h': No such file or directory
[\code]
Bref je comprend bien la qu'il s'agit de problèmes de référence à ces différents fichiers mais ma question est la suivante :
quelles librairies dois je utiliser ?
en cherchant sur le net (et oui google ami du développeur) j'ai lu qu'il s'agirait de librairies unix et pas dispo sur windows est ce que ce post que j'ai vu est dans le vrai ?
Si oui quelqu'un a - t - il un bout de code avec les libs nécessaires pour faire communiquer deux postes en multicast ?

Je vous remercie d'avance pour vos réponses.

Vinzouille

samedi 16 février 2008 à 18:38:33 | Re : multicast en c sous windows

rt15

Membre Club Administrateur CodeS-SourceS
Réponse acceptée !
Salut,

Tu peux virer les trois quarts des includes. stdio, time et winsock devrait suffires.
Plus d'infos sur la compatibilité socket Linux/Windows.
Il faut appeler WSAStartup et WSACleanup.

L'aide de setsockopt de la msdn.

D'après cette page de man, l'option IP_ADD_MEMBERSHIP permet de rejoindre un groupe de multicast (Et donne la déclaration de la structure ip_mreq).

L'option IP_ADD_MEMBERSHIP ne semble pas disponible avec winsock2.h, mais elle à l'air ok pour winsock.h.

Le compilo à refusé de casté :
      if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
             &mreq, sizeof(mreq)) < 0) {

=>

      if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
             &(char *)mreq, sizeof(mreq)) < 0) {

Un article sur le multicast sous windows.

dimanche 17 février 2008 à 01:42:15 | Re : multicast en c sous windows

tenrod

Ok merci rt15 je vais fouiller du coté des liens que tu m'as filé et je te tiens au courant dès que j'ai du neuf

Vinzouille

lundi 18 février 2008 à 10:11:00 | Re : multicast en c sous windows

tenrod

Impec tes exemples m'ont permis de mieux comprendre le systeme des sockets sous windows (jusque la je ne l'avais fait que sous linux...)

Pour ceux qui auraient le meme problème j'ai trouvé ce petit lien qui n'est pas dénué d'intéret

[ Lien ]

Vinzouille

jeudi 21 février 2008 à 23:28:11 | Re : multicast en c sous windows

tenrod

Salut a tous!
J'ai malheureusement un pb supplémentaire avec mes socket en multicast ...
ça se passe a ce niveau

if ((setsockopt(sock_rec, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req, sizeof(mc_req))) < 0)
    {
        printf("setsockopt - IP_ADD_MEMBERSHIP");
        system("PAUSE");
        exit(1);
    }

en fait le "IP_ADD_MEMBERSHIP" ne passe pas, y'a t'il une manipulation spéciale a faire sur ma machine ou y'a il erreur de code?

pour info voici tout le code :

#include <sys/types.h> 
#include <winsock2.h>  
#include <ws2tcpip.h>  
#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>

#define GROUP    "239.137.194.222"
#define PORT    55501
#define MAX_LEN  1024   //taille max réception

int main()
{
    int reuse;
    int sock_rec;                 /* descripteur socket */
    int flag_on = 1;              /* flag socket */
    struct sockaddr_in mc_addr_rec;   /* structure d'adresse de la socket reception */
    char recv_str[MAX_LEN+1];     /* buffer de réception */
    int recv_len;                 /* longueur de la string en réception */
    struct ip_mreq mc_req;        /* structure multicast */
    struct sockaddr_in from_addr; /* source */
    unsigned int from_len;        /* longueur source */
    WSADATA wsaData;              /* structure DLL socket Windows */
    int sock_send;              /* descripteur socket */
    char send_str[MAX_LEN];     /* string à envoyer */
    int send_len;               /* longueur string à envoyer */
    struct sockaddr_in mc_addr_send;   /* structure d'adresse de la socket emission */
    unsigned char ttl=1;     /* time to live */
   
    /* Initialisation de Winsock */
    if (WSAStartup(MAKEWORD(2,0), &wsaData)!=0)
    {
       printf("\nWSAStartup() erreur");
    }
   
    /* création de la socket de réception */
    if ((sock_rec = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    {
       printf("socket() reception erreur");
    }
   
    /* création de la socket de d'émission */
    if ((sock_send = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    {
       printf("socket() emission erreur");
    }
   
    /*initialisation de la socket de reception*/
    memset(&mc_addr_rec, 0, sizeof(mc_addr_rec));
    mc_addr_rec.sin_family      = AF_INET;
    mc_addr_rec.sin_addr.s_addr = htonl(INADDR_ANY);
    mc_addr_rec.sin_port        = htons(PORT);
   
    /*initialisation de la socket d'emission*/
    memset(&mc_addr_send, 0, sizeof(mc_addr_send));
    mc_addr_send.sin_family      = AF_INET;
    mc_addr_send.sin_addr.s_addr = htonl(INADDR_ANY);
    mc_addr_send.sin_port        = htons(PORT);
   
    recv_len = sizeof(mc_addr_rec);
    from_len = sizeof(mc_addr_send);
   
    if ((setsockopt(sock_rec, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req, sizeof(mc_req))) < 0)
    {
        printf("setsockopt - IP_ADD_MEMBERSHIP");
        system("PAUSE");
        exit(1);
    }
   
    if (bind(sock_rec, (struct sockaddr *)&mc_addr_rec, sizeof(mc_addr_rec)) < 0)
    {
        printf("bind");
        system("PAUSE");
        exit(1);
    }
   
    /*réception des datagrammes*/
    while (1)
    {
        if (recvfrom(sock_rec, recv_str, sizeof(recv_str), 0, (struct sockaddr *)&mc_addr_rec, &recv_len) < 0)
        {
            printf("recvfrom");
            system("PAUSE");
            exit(1);
        }
        else
        { /* fin de transmission */
            break;
        }
        printf("%s\n", recv_str); /* affichage du message */
    }
   
    /*opération qui permet de fixer la valeur du TTL*/
    if (setsockopt(sock_send, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1)
    {
        printf("setsockopt: IP_MULTICAST_TTL");
    }
   
    /*emission des datagrammes*/
    if (sendto(sock_send, send_str, strlen(send_str), 0, (struct sockaddr *)&mc_addr_send, send_len) < 0)
    {
        printf("sendto");
        system("PAUSE");
        exit(1);
    }
   
    /*quitter le groupe*/
    if (setsockopt(sock_rec, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mc_req, sizeof(mc_req)) == -1)
    {
        printf("setsockopt: IP_DROP_MEMBERSHIP");
    }
   
    /*port réutilisable*/
    reuse = 1;
    if (setsockopt(sock_rec, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse)) == -1) {
        printf("setsockopt: SO_REUSEADDR");
    }
   
    system("PAUSE");   
    return 0;
}

Vinzouille

jeudi 21 février 2008 à 23:41:42 | Re : multicast en c sous windows

rt15

Membre Club Administrateur CodeS-SourceS
Des fois, la solution est plus prète qu'on le pense.
Je cite mon message plus haut :

L'option IP_ADD_MEMBERSHIP ne semble pas disponible avec winsock2.h, mais elle à l'air ok pour winsock.h.

Pourtant, tu utilises windock2.h dans ton code...

jeudi 21 février 2008 à 23:46:33 | Re : multicast en c sous windows

tenrod

Salut et merci pour ton aide
bon j'ai remplacé le winsock2.h par winsock.h mais je me retrouve toujours avec le meme pb ...

Vinzouille

vendredi 22 février 2008 à 00:46:00 | Re : multicast en c sous windows

rt15

Membre Club Administrateur CodeS-SourceS
mmm...

Tu utilises quel IDE ?
Parce que par exemple dans ce winsock.h, il y est.


vendredi 22 février 2008 à 10:08:02 | Re : multicast en c sous windows

tenrod

Je suis sous dev c++.
Mon OS est windows XP media center
Le pire c'est que j'ai un autre bout de code qui utilise cette méthode et la ça passe ...
Je vais relire encore et encore mon code (même si je doute que ça serve a quelquechose) histoire de voir si j'ai pas zappé une partie vitale ...

Vinzouille

vendredi 22 février 2008 à 10:22:00 | Re : multicast en c sous windows

tenrod

Bon finalement la relecture a porté ses fruits !
C'est fou ce que ça fait du bien une bonne nuit de sommeil lool
Alors pour ceux que ça intéresse voici le code revu et corrigé :

#include <sys/types.h> 
#include <winsock.h>  
#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>

#define GROUP "239.137.194.222"
#define PORT 55501
#define MAX_LEN  1024   //taille max réception

int main()
{
    int reuse;
    int sock_rec;                 /* descripteur socket */
    int flag_on = 1;              /* flag socket */
    struct sockaddr_in mc_addr_rec;   /* structure d'adresse de la socket reception */
    char recv_str[MAX_LEN+1];     /* buffer de réception */
    int recv_len;                 /* longueur de la string en réception */
    struct ip_mreq mc_req;        /* structure multicast */
    struct sockaddr_in from_addr; /* source */
    unsigned int from_len;        /* longueur source */
    WSADATA wsaData;              /* structure DLL socket Windows */
    int sock_send;              /* descripteur socket */
    char send_str[MAX_LEN];     /* string à envoyer */
    int send_len;               /* longueur string à envoyer */
    struct sockaddr_in mc_addr_send;   /* structure d'adresse de la socket emission */
    unsigned char ttl=1;     /* time to live */
   
    /* Initialisation de Winsock */
    if (WSAStartup(MAKEWORD(2,0), &wsaData)!=0)
    {
       printf("WSAStartup() erreur");
    }
   
    /* création de la socket de réception */
    if ((sock_rec = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    {
       printf("socket() reception erreur");
    }
   
    /* création de la socket de d'émission */
    if ((sock_send = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    {
       printf("socket() emission erreur");
    }
   
    if ((setsockopt(sock_rec, SOL_SOCKET, SO_REUSEADDR, (char*)&flag_on,sizeof(flag_on))) < 0)
    {
       printf("setsockopt() erreur - SO_REUSEADDR");
    }
   
    /*initialisation de la socket de reception*/
    memset(&mc_addr_rec, 0, sizeof(mc_addr_rec));
    mc_addr_rec.sin_family      = AF_INET;
    mc_addr_rec.sin_addr.s_addr = htonl(INADDR_ANY);
    mc_addr_rec.sin_port        = htons(PORT);
   
    /*initialisation de la socket d'emission*/
    memset(&mc_addr_send, 0, sizeof(mc_addr_send));
    mc_addr_send.sin_family      = AF_INET;
    mc_addr_send.sin_addr.s_addr = htonl(INADDR_ANY);
    mc_addr_send.sin_port        = htons(PORT);
   
    recv_len = sizeof(mc_addr_rec);
    from_len = sizeof(mc_addr_send);
   
    if (bind(sock_rec, (struct sockaddr *)&mc_addr_rec, sizeof(mc_addr_rec)) < 0)
    {
        printf("bind erreur");
        system("PAUSE");
        exit(1);
    }
   
    mc_req.imr_multiaddr.s_addr = inet_addr(GROUP);
    mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
   
    if (setsockopt(sock_rec, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mc_req, sizeof(mc_req)) < 0)
    {
        printf("setsockopt erreur - IP_ADD_MEMBERSHIP");
        system("PAUSE");
        exit(1);
    }
   
   
   
    /*réception des datagrammes*/
    while (1)
    {
        if (recvfrom(sock_rec, recv_str, sizeof(recv_str), 0, (struct sockaddr *)&mc_addr_rec, &recv_len) < 0)
        {
            printf("recvfrom erreur");
            system("PAUSE");
            exit(1);
        }
        else
        { /* fin de transmission */
            break;
        }
        printf("%s\n", recv_str); /* affichage du message */
    }
   
    /*opération qui permet de fixer la valeur du TTL*/
    if (setsockopt(sock_send, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1)
    {
        printf("setsockopt: IP_MULTICAST_TTL");
    }
   
    /*emission des datagrammes*/
    if (sendto(sock_send, send_str, strlen(send_str), 0, (struct sockaddr *)&mc_addr_send, send_len) < 0)
    {
        printf("sendto");
        system("PAUSE");
        exit(1);
    }
   
    /*quitter le groupe*/
    if (setsockopt(sock_rec, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mc_req, sizeof(mc_req)) == -1)
    {
        printf("setsockopt: IP_DROP_MEMBERSHIP");
    }
   
    /*port réutilisable*/
    reuse = 1;
    if (setsockopt(sock_rec, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse)) == -1) {
        printf("setsockopt: SO_REUSEADDR");
    }
   
    system("PAUSE"); 
    return 0;
}

En tout cas merci pour l'aide ^^

Vinzouille


1 2

Cette discussion est classée dans : message, include, sock, addr, if


Répondre à ce message

Sujets en rapport avec ce message

Client/Serveur avec thread sous linux [ par frater_sinister ] J'ai un prblm avec ce programme. Avant tout le but de ce code: le client envoit un fichier au serveur, ce dernier renvoit le nombre de lignes/mots/let pb communication socket [ par skyman272 ] bonjourvoici un petit programme client/serveur pour un projet à l'insa (sous linux).Le programme client envoi un message au programme serveur qui lui telechargement d'un fichier sur internet [ par fredleconte ] Salut, Voila j'essaie de telecharger un fichier http mais je ne sais pas comment recevoir le fichier help please. voici le programme: // Download d'u socket trop lents [ par cid7777777 ] bonjour,jessaye de faire un jeu qui peu se jouera 2 en reseau local.je ne connais absolument rien en reso, mais en fouillant sur le net,  jai trouver Problème de connexion Socket [ par qhhu ] Bonjour !En temp normal, je programme en java, mais j'ai voulu essayer le c++parce que je trouve que c'est interessant de connaître plusieurs language RESEAU PAR SOCKET EN C [ par aziatedu13 ] bonjour,je veux faire un truk extremement simple pour certain, mais assez très difficile pour moi..voila je souhaiterai pouvoir afficher dans une cons C++ Serveur web [ par kiki67100 ] Bonjour J'ai commencé a faire un serveur Pour affiché du texte sur le client Voici le code#include #include #include #include c<br téléchargement d'un fichier via l'url [WINSOCK] [ par MorbhAck ] Bonsoir tout le monde!j'ai un problème, j'essai de télécharger un fichier .rar avec GETet quand je veux extraire le rar il m'indique que le fichier es pb pr écouter sur un port... [ par Gendal67 ] Bonsoir all...J'avais envie de créer une application utilisant les sockets liées à une connection TCP/IP qui écoute sur un port précis. Jusque là, pas Multiples messages non reçus...:(( [ par Gendal67 ] Bonsoir tout le monde!Je suis actuellement en cours d'apprentissage des Sockets et j'ai crée une application Client/Server pouvant communiquer ensembl


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 8,174 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales