IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Windows, sockets et plusieurs cartes réseaux


Sujet :

Réseau C

  1. #1
    Invité(e)
    Invité(e)
    Par défaut Windows, sockets et plusieurs cartes réseaux
    Bonjour,

    Sur un premier socket, j'agis en client, je reçoit des données.

    Sur un autre socket, j'aimerais agir en serveur pour renvoyer les données transformées.

    Quand je fait tout sur une seule carte réseau, pas de problème, en revanche quand je veux être client sur une carte et serveur sur l'autre, ça coince : Je ne contrôle pas quelle carte va être utilisée par mon serveur...

    Le serveur en question est un serveur multicast qui émet en 224.0.0.1, il est possible de fixer les adresses IP des cartes, mais elles sont du genre 192.168.x.y.

    Comment faire pour choisir sur quel réseaux va être diffusé mon serveur ?

    Merci d'avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    /**
     * build with gcc -Wall -Wextra main.c  -lws2_32 -mno-cygwin
     */
    int main(void)
    {
        SOCKET sock;
        unsigned char ttl = 1;
        SOCKADDR_IN from;
        size_t i;
        WSADATA wsa;
     
        /* init winsock2 */
        WSAStartup(MAKEWORD(2, 2), &wsa);
     
        /* creation du socket */
        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (INVALID_SOCKET == sock) {
            perror("socket");
            goto EXIT;
        }
     
        /* mis en place multicast */
        if (-1 ==
            setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
                       sizeof(ttl))) {
            perror("setsockopt");
            closesocket(sock);
            goto EXIT;
        }
        /* un message de test, envoyé plusieurs fois pour avoir une trace dans 
           l'activité réseau */
        from.sin_family = AF_INET;
        from.sin_port = htons(7766);
        from.sin_addr.s_addr = inet_addr("224.0.0.1");
        for (i = 0; i < 15000; ++i) {
            char buff[] = "Hello world";
            sendto(sock, buff, sizeof(buff), 0, (SOCKADDR *) & from,
                   sizeof(from));
        }
    EXIT:
        /* fermeture winsock32 */
        WSACleanup();
        return EXIT_SUCCESS;
    }

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    J'ai lu en diagonal, donc je vais peut être répondre à côté. Mais normalement, tu utilises bind pour spécifier l'interface sur laquelle tu veux que ta socket travaille. En toute logique, tu dois faire un bind sur l'@ de ta première carte avec ta socket client et sur l'@ de la seconde pour ta socket serveur.
    [EDIT] Beurk; j'ai vu un goto

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    tu utilises bind pour spécifier l'interface sur laquelle tu veux que ta socket travaille.
    Ok, je pensais que bind était réservé au TCP.
    Je teste ça dès demain...
    Citation Envoyé par 3DArchi Voir le message
    [EDIT] Beurk; j'ai vu un goto
    C'est voulu, c'est juste un code de test que j'ai écrit pour poster.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Le bind n'est ni TCP ni UDP, mais associe une adresse à ta socket:
    Citation Envoyé par MSDN
    The bind function associates a local address with a socket.

  5. #5
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 382
    Points
    5 382
    Par défaut
    Salut,

    Perso, je n'ai jamais trouvé de solution.
    J'avais pas tout a fait la même config : 1 carte et 2 IP (ex 199.0.0.100 et 192.168.0.100).

    Mon PC demandait des infos via multicast (ex : données venant de 239.0.0.10), c'était l'IP 199.0.0.100 qui la demandais. Et quand le routeur demandait au PC "as-tu des abonnements en cours ?", l'IP 192.168.0.100 disais "non", et hop, je perdais le flux multicast.

    Mais ton pb n'est pas le même.
    Physiquement, tes 2 cartes réseaux sont-elles sur 2 réseaux différents ?

    PS : il me semble que diffuser sur 224.0.0.1 n'est pas recommandé. (ca ressemble à du broadcast)

  6. #6
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi
    En toute logique, tu dois faire un bind sur l'@ de ta première carte avec ta socket client et sur l'@ de la seconde pour ta socket serveur.
    C'est bien ça que je veux faire, plus qu'à trouver comment ; un simple bind ne colle pas (ou alors, je n'ai pas encore trouvé les bon paramètres), mais maintenant, je sait au moins avec quels mots clef chercher.
    Merci

    Citation Envoyé par fregolo52 Voir le message
    Physiquement, tes 2 cartes réseaux sont-elles sur 2 réseaux différents ?
    Oui, justement pour que le reste du réseau ne voit pas le ou les éléments qui m'envoient des données
    Citation Envoyé par fregolo52 Voir le message
    PS : il me semble que diffuser sur 224.0.0.1 n'est pas recommandé. (ca ressemble à du broadcast)
    De ce côté, je suis un peu perdu, mais il me semble que c'est bien ça que je voulais faire : diffuser sur une adresse multicast (qui commence donc à 224.0.0.1) pour que n'importe quelle machine du réseau auquel appartient la carte qui émet puisse récupérer le flux.

    Cela dit, l'émission ne pose pas problème : mon serveur diffuse en 224.0.0.1 et les clients arrivent à récupérer des données.

    Hors Sujet :
    J'ai trouvé ce qu'il me faut... mais cela reste spécifique à linux
    Citation Envoyé par man socket
    SO_BINDTODEVICE
    Attacher cette socket à un périphérique donné, tel lqeth0rq, comme indiqué dans le nom d'interface transmis. Si la socket est attachée à une interface, seuls les paquets reçus sur cette interface particulière sont traités par la socket.

  7. #7
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 382
    Points
    5 382
    Par défaut
    En effet, notre projet était sous windows et Linux, et en effet quand je regardais le man et la MSDN pour la fonction sendto (entre autre), sous Linux il y a beaucoup plus d'option.

    Une solution (qui peut prendre beaucoup de temps) est de regarder Winpcap, librairie utilisée par Ehtereal, il y a surement plus de possibilité que les fonctions de base de l'api windows.

  8. #8
    Invité(e)
    Invité(e)
    Par défaut
    J'ai parlé trop vite, bind a l'air de fonctionner parfaitement sous vista (en fait hier soir tard, j'avais fait des tests non concluants sous OS X)

    Merci bien 3DArchi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    /**
     * build with gcc -Wall -Wextra main.c -lws2_32 -mno-cygwin
     */
     
    #define IP_LOCAL "192.168.1.21"
    #define IP_BROADCAST "224.0.0.1"
    #define IP_PORT 7766
    int main(void)
    {
        SOCKET sock = INVALID_SOCKET;
        unsigned char ttl = 1;
        SOCKADDR_IN from, local;
        size_t i;
        WSADATA wsa;
     
        /* init winsock2 */
        WSAStartup(MAKEWORD(2, 2), &wsa);
     
        /* creation du socket */
        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (INVALID_SOCKET == sock) {
            perror("socket");
            goto EXIT;
        }
     
        /* mise en place du multicast */
        if (0 !=
            setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
                       sizeof(ttl))) {
            perror("setsockopt");
     
            goto EXIT;
        }
     
        /* bind sur l'adresse IP de la carte réseau voulue */
        local.sin_family = AF_INET;
        local.sin_port = htons(IP_PORT);
        local.sin_addr.s_addr = inet_addr(IP_LOCAL);
        if(0 != bind(sock, (SOCKADDR *) & local, sizeof(local))) {
            perror("bind");
            goto EXIT;
        }
     
        /* un message de test, envoyé plusieurs fois pour avoir une trace dans 
           l'activité réseau */
        from.sin_family = AF_INET;
        from.sin_port = htons(IP_PORT);
        from.sin_addr.s_addr = inet_addr(IP_BROADCAST);
        for (i = 0; i < 1500000; ++i) {
            char buff[] = "Hello world";
            sendto(sock, buff, sizeof(buff), 0, (SOCKADDR *) & from,
                   sizeof(from));
        }
    EXIT:
        if(INVALID_SOCKET != sock) {
            closesocket(sock);
        }
        /* fermeture winsock32 */
        WSACleanup();
        return EXIT_SUCCESS;
    }
    Un dernier point, mais que je ne vais pas m'amuser à corriger dans l'immédiat, il n'est plus possible d'installer un client[1] pour ce serveur sur la même machine... dans la mesure où au final, le client sera sur une autre machine, c'est pas génant.

    [1] enfin d'utiliser le petit client de test qui fonctionnait bien quand le serveur ne faisait pas de bind.

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par mabu Voir le message
    Un dernier point, mais que je ne vais pas m'amuser à corriger dans l'immédiat, il n'est plus possible d'installer un client[1] pour ce serveur sur la même machine... dans la mesure où au final, le client sera sur une autre machine, c'est pas génant.

    [1] enfin d'utiliser le petit client de test qui fonctionnait bien quand le serveur ne faisait pas de bind.
    9 chance sur 10 que cela puisse se corriger avec setsockopt(SO_REUSEADDR).

Discussions similaires

  1. Réponses: 7
    Dernier message: 20/03/2011, 14h26
  2. Carte Réseaux avec plusieurs ports
    Par mambo dans le forum Administration
    Réponses: 5
    Dernier message: 18/05/2009, 14h09
  3. Adresse MAC Plusieurs cartes réseaux
    Par DMboup dans le forum Access
    Réponses: 3
    Dernier message: 13/07/2008, 00h11
  4. Cartes réseaux virtuelles
    Par Lex99 dans le forum Développement
    Réponses: 2
    Dernier message: 07/02/2005, 21h54
  5. construire 1 gateway avec 1 carte réseaux sous débian
    Par regular dans le forum Développement
    Réponses: 4
    Dernier message: 28/08/2003, 01h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo