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

C++ Discussion :

[R�seau] Winsock 2 ; configuration d'un port source


Sujet :

C++

  1. #1
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut [R�seau] Winsock 2 ; configuration d'un port source
    Bonjour a tous,
    le probleme est le suivant: j'envoie des paquets par UDP a une machine sur un port de destination donne a partir d'un port aleatoirement attribue.
    Je cherche simplement la fonction me permettant de fixer le port source (j'ai effectue pas mal de recherches mais tres peu de resultats sont apparus, la seule "solution" que j'ai trouve (sur ce site mais en section c#) c'est de faire un bind de la socket sur le port, mais cela ne fonctionne pas).
    Je bosse avec Winsock 2

    Merci d'avance

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Il me semble que faire un bind de la socket sur le port est LA solution pour �a...
    En quoi cela ne marche-t-il pas exactement ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    Merci pour la reponse. En fait cela ne fonctionne pas dans la mesure ou le port source est toujours aleatoire =/
    La situation n'a pas evolue avec cette fonction en fait.

  4. #4
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    voici le code :

    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
     
    void DLL_EXPORT sendMulticast(unsigned char *send_str, int send_len, int type, int port, char *group)
    {
        int             sock;                   /* socket descriptor */
        struct          sockaddr_in mc_addr;    /* socket address structure */
        char            *mc_addr_str;           /* multicast IP address */
        unsigned short  mc_port;                /* multicast port */
        unsigned char   mc_ttl=1;               /* time to live (hop count) */
     
        mc_addr_str = group;        /* arg 1: multicast IP address */
        mc_port     = port;         /* arg 2: multicast port number */
     
        /* create a socket for sending to the multicast address */
        sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     
        /* set the TTL (time to live/hop count) for the send */
        setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*) &mc_ttl, sizeof(mc_ttl));
     
        /* construct a multicast address structure */
        memset(&mc_addr, 0, sizeof(mc_addr));
        mc_addr.sin_family      = AF_INET;
        mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
        mc_addr.sin_port        = htons(mc_port);
        bind(sock, (SOCKADDR*) &mc_addr, sizeof(mc_addr));
     
        sendto(sock, (char *)send_str, send_len, 0, (struct sockaddr *) &mc_addr, sizeof(mc_addr));
     
        closesocket(sock);
    }
    WSAStartup a ete utilise avant l'appel de cette fonction, la dll est donc bien chargee.

  5. #5
    R�dacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en s�curit�
    Inscrit en
    Mai 2007
    Messages
    11 517
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 62
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : Consultant en s�curit�
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par d�faut
    Il te faut 2 structures sockaddr_in

    1 pour d�crire le destinataire (tu l'as d�j� faite)
    1 pour d�crire le bind de ton socket en local. et dans celle l�, je pense qu'il faut initialiser le membre ".sin_addr.s_addr" = avec la valeur INETADDR_ANY
    Raymond
    Vous souhaitez participer � la rubrique R�seaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs syst�me et r�seau � configurer leurs �quipements SNMP r�seau.
    e-verbe Un logiciel de conjugaison des verbes de la langue fran�aise.

    Ma page personnelle sur DVP
    .

  6. #6
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    Je viens de tenter avec une nouvelle structure initialisee de la meme maniere que la premiere, cependant ca ne fonctionne toujours pas.
    pour la premiere il me dit a la compilation : "error: `INETADDR_ANY' was not declared in this scope"
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    mc_addr2.sin_addr.s_addr = htonl(INETADDR_ANY);
    j'ai egalement essaye :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    mc_addr2.sin_addr.s_addr = htonl(INADDR_ANY);
    Mon IDE est code::blocks.
    J'utilise le compilateur mingw32-g++.

  7. #7
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Utilises 0 !
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    #define INADDR_ANY              (ULONG)0x00000000
    Mais bon... c'est �tonnant qu'il ne soit pas d�fini... c'est quand m�me la base des winsocks

  8. #8
    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
    Par d�faut
    Quelque chose de ce gout l�:
    -> gethostname pour retrouver ton adresse locale sous forme de nom
    -> gethostbyname pour retrouver ton adresse IP
    -> bind sur cette adresse avec le port UDP
    -> sendto sur l'adresse + port destinataire.
    Les deux premiers peuvent aussi �tre remplac� par l'utilisation de 127.0.0.1 comme adresse locale.

  9. #9
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    @nicroman : INADDR_ANY etait bien defini lui, mais j'ai quand meme tente de le definir sous un autre nom pour l'essayer, mais ca n'a pas fonctionne

    @3DArchi : j'ai tente ces etapes, mais le probleme est toujours le meme

    Je vais le reexpliquer au cas ou je me sois mal exprime ce qui vous aurait oriente vers une fausse piste (on ne sait jamais, et moi encore moins ) :

    j'envoie des paquets a partir d'un port X, vers le port A d'un destinataire. Celui-ci le recoit. Il me repond en m'envoyant un paquet a partir du port A, vers le port X de mon pc.
    Le probleme c'est que le port X est aleatoire, or j'aimerais prevoir le port utilise pour etre capable de recevoir le paquet envoye en reponse par ma cible. Mon but ici est donc de figer le port X pour savoir ou recevoir les paquets (je n'ai pas acces au soft de la cible pour forcer le port de destination).

    J'utilise le protocole UDP, la communication se fait a travers le multicast (les machines triant les paquets qui leur sont destines).
    La librairie utilisee est Winsock2, mon IDE Code::Blocks, mon compilateur mingw32-g++.
    Le produit de la compilation est une DLL utilisee par un programme dans un autre langage (ca n'a pas d'importance ici, du moins j'en doute).

    Je vous dit pour les reponses qui ont deja ete donnees.

  10. #10
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    Eureka!

    C'est assez "idiot", en fait il y a une information que je ne vous ai pas donne (ca m'est completement sorti de la tete, comme quoi on ne se relit jamais assez) : une autre socket utilise ce port, pour traiter les paquets entrants. Cette socket possede l'option SO_REUSEADDR, pour que l'adresse puisse etre reutilisee. Cependant, pour que la socket d'envoi puisse etre bind sur le meme port, elle doit elle-meme etre parametree avec cette option.

    Voici le code pour ceux que ca interresserait :
    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
     
    void DLL_EXPORT sendMulticast(unsigned char *send_str, int send_len, int type, int port, char *group)
    {
        int             sock;                   /* socket descriptor */
        struct          sockaddr_in mc_addr;    /* socket address structure */
        struct          sockaddr_in mc_addr2;   /* socket bind structure */
        char            *mc_addr_str;           /* multicast IP address */
        unsigned short  mc_port;                /* multicast port */
        unsigned char   mc_ttl=1;               /* time to live (hop count) */
     
        mc_addr_str = group;        /* arg 1: multicast IP address */
        mc_port     = port;         /* arg 2: multicast port number */
     
        /* create a socket for sending to the multicast address */
        sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     
        /* set the TTL (time to live/hop count) for the send */
        setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*) &mc_ttl, sizeof(mc_ttl));
     
        int flag_on = 1;            /* socket option flag */
        /* Make the socket reusable,
        any other socket must be set with this option if they use the same port */
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flag_on, sizeof(flag_on));
     
        /* construct a multicast address structure */
        memset(&mc_addr, 0, sizeof(mc_addr));
        mc_addr.sin_family      = AF_INET;
        mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
        mc_addr.sin_port        = htons(mc_port);
     
        /* construct socket bind structure*/
        memset(&mc_addr2, 0, sizeof(mc_addr));
        mc_addr2.sin_family      = AF_INET;
        mc_addr2.sin_addr.s_addr = htons(INADDR_ANY);
        mc_addr2.sin_port        = htons(mc_port);
        /* bind the port in order to set the source port */
        bind(sock, (SOCKADDR*) &mc_addr2, sizeof(mc_addr2));
     
        /* send to the multicast group "group" on the port "port" from the port "port" */
        sendto(sock, (char *)send_str, send_len, 0, (struct sockaddr *) &mc_addr, sizeof(mc_addr));
     
        /* close the socket */
        closesocket(sock);
    }
    Je vous remercie pour votre participation, et pour les solutions que vous m'avez apporte !
    Vive developpez !

  11. #11
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Forc�ment... si on a que la moiti� du probleme, et que tu nous dis pas que ca foirait � l'execution avec une erreur "address already in use" !!!! ...

    Moi j'�tais rest� sur le probl�me de compilation

    Sinon.... tu n'as pas besoin de fixer le port X d'origine... tu l'as � la reception dans le paquet... (ca te permettra en plus de passer le port-masquerading �ventuels).


    Genre:
    A envoit un paquet (port 'libre' Ax) � B sur le port Bx (fix� lui).
    B recoit le paquet, et, dans l'addresse d'origine a bien A,Ax ....

    Si il y a du NAT entre les deux, tu recevra bien C,Cx qu'il faut utiliser pour toucher A,Ax !

  12. #12
    Membre r�gulier
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut
    tu n'as pas besoin de fixer le port X d'origine... tu l'as � la reception dans le paquet
    Le probleme c'est que je suis le premier a envoyer le paquet, je n'ai donc aucune info a la base, c'est a moi de definir tout ca.

    Je debute dans le reseau (ca fait meme pas un mois que j'ai commence), et c'est pas super simple, d'ailleurs j'ai du relire plusieurs fois ce que tu as explique (j'ai meme sollicite google)

    Merci pour l'aide!

  13. #13
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Dans toute application client-serveur, il faut, � un moment donn� avoir une adresse fixe.
    Quand je parle d'adresse, j'entends adresse du protocol, c'est � dire un couple IP/port pour le protocol UDP ou TCP.
    Et bien sur, ca peut �tre une adresse multicast voir broadcast (pour toucher toutes les machines sur le r�seau local).

    Disons que S est cette adresse fixe.

    Maintenant, j'ai un client qui veut acc�der � S... Le client va donc cr�er une adresse "locale" C (ou bien statiquement avec 'bind' ou bien automatiquement, sans 'bind') et acc�der � S ('sendto(S,data)').

    Quand S va recevoir le paquet UDP, il va faire: 'recvfrom(?,data)' et recevra donc une adresse.
    Dans les cas simples (m�me r�seau local, adresses IP publiques) cette adresse sera C... mais pas toujours....
    Dans les cas classiques (serveur et client sur des r�seaux locaux diff�rents, et utilisant des adressages priv�s) l'adresse sera D !!
    Car entre C et S, un appareil de routage s'amusera � modifier l'adresse d'origine du paquet en "D"... (ce qu'on appelle le PAT/NAT), et le seul moyen de remonter � C c'est de communiquer avec cette adresse D.

    Utiliser un port fixe pour un 'client' est donc non seulement dangereux, mais *tres* compliqu� parceque n�cessitant de mettre en place des r�gles de routage.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 4
    Dernier message: 13/08/2007, 09h47
  2. R�ponses: 1
    Dernier message: 29/09/2006, 13h26
  3. [R�seau local] Impossible d'ouvrir un port!
    Par webrider dans le forum Hardware
    R�ponses: 3
    Dernier message: 10/08/2006, 08h51
  4. Configurer APACHE malgr� PORT 80 ferm� ?
    Par Sparkle dans le forum Apache
    R�ponses: 2
    Dernier message: 20/07/2006, 13h15
  5. configuration d'un port PCI
    Par ptifleure dans le forum MFC
    R�ponses: 2
    Dernier message: 11/04/2006, 10h08

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