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 :

Problème avec l'adresse d'une socket


Sujet :

Réseau C

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 5
    Points : 4
    Points
    4
    Par défaut Problème avec l'adresse d'une socket
    Bonjour ,

    J'ai une question en ce qui concerne quelques lignes de codes sur les socket. Voici ce qui pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    target_addr.sin_addr = *((struct in_addr *) host_info->h_addr);
    Cependant, je ne comprend pas pourquoi on utilise pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    target_addr.sin_addr.s_addr = *((struct in_addr *) host_info->h_addr)
    ;

    Depuis le debut, j'ai compris que pour rentrer une adresse ip on mettait "target_addr.sin_addr.s_addr = ...".
    Ici, dans mon cas, je crée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct hostent *host_info;
    struct sockaddr_in target_addr;
    On récupère ensuite l'adresse ip de l'hôte par la fonction gethostbyname(argv[1]), néanmoins, je ne comprend pas pourquoi lorsqu'on rentre l'adresse ip c'est à dire host_info->h_addr on ne met pas le s_addr à la suite de target_addr.sin_addr...
    Après quelques heures de méditation () sur ce problème, pourriez vous m'expliquer ce que l'on fait réellement dans le cas énoncé ci dessus et aussi quelle est la différence entre sin_addr et s_addr ?
    Quel lien y'a t'il entre s_addr, sin_addr, et h_addr ?

    Merci de votre aide

    Extrait du code source ( fatal est une fonction que j'ai crée ) :
    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
     
    int main(int argc, char *argv[]) {
     
       int sockfd;
       struct hostent *host_info;
       struct sockaddr_in target_addr;
       unsigned char buffer[4096];
     
       if(argc < 2) {
          printf("Usage: %s <hostname>\n", argv[0]);
          exit(1);
       }
     
       if((host_info = gethostbyname(argv[1])) == NULL) {
          fatal("looking up  hostname");
       }
       if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
          fatal("in socket");
       }
     
       target_addr.sin_family = AF_INET;
       target_addr.sin_port = htons(80);
       target_addr.sin_addr = *((struct in_addr *) host_info->h_addr);
       memset(&(target_addr.sin_zero), '\0', 8);
    ...

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Hello,

    Pour faire simple, l'API des sockets est très fouillis, parce qu'elle a été définie très tôt, avant que la programmation objet soit largement répandue et que les programmeurs soient habitués à ce genre de cas.

    Apparemment, on estimait à l'époque que l'adresse elle-même allait recevoir des éléments futurs, qui seraient soit des attributs, soit des sous-composants de l'adresse Internet. Dans les faits, le format n'a jamais changé et cette organisation a été figée en l'état, même si elle est un peu superflue.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Merci de ta réponse mais je n'ai toujours pas compris ce que je dois comprendre ()...
    Le fait est que de ne pas utiliser le s_addr m'embrouille et je ne comprend pas ce que je fais réelement dans mon code (ce qui est embêtant ).

    Bref, pourquoi fais-ton:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    target_addr.sin_addr = *((struct in_addr *) host_info->h_addr);
    au lieu de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    target_addr.sin_addr.s_addr = *((struct in_addr *) host_info->h_addr)
    (qui ne marche pas forcement)

    C'est la notation qui me gêne... Y'aurai t'il un équivalent mais avec target_addr.sin_addr.s_addr = ...

    je désespère un peu

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    À cause d'une bidouille assez sale ! :-)

    • h_addr est un « char * », qui pointe en réalité l'adresse de l'hôte, ou la première adresse s'il y a plusieurs alternatives. Cette adresse est donc une suite de quatre octets dans l'ordre du réseau (en principe Big Endian, donc, mais on s'en fiche) ;
    • sin_addr est une structure censée décrire de façon exhaustive une adresse Internet mais qui, dans les faits, qu'un seul champ de type uint32_t (« s_addr »). Ce champ — et donc la totalité de la structure — font donc exactement quatre octets eux-aussi ;
    • Là encore, ces octets contiennent une adresse au format réseau ;
    • La norme C te garantit que le premier membre d'une structure est toujours aligné avec le début de celle-ci, donc que l'adresse du premier membre est celle de la structure. C'est pratique lorsque tu utilises des unions de structures par exemple. Toutes les structures peuvent alors être dotées d'un membre commun « type » qui permet de savoir à quoi on a affaire et qui peut être lu même sans savoir quel objet on a reçu ;
    • Du coup, l'adresse de « sin_addr » en général est toujours la même que « sin_addr.s_addr ».


    Effectivement, sur le plan technique, c'est « s_addr » qui aurait dû être rempli. Ce sont les deux vrais champs réputés être composés de la même façon et si jamais quelqu'un étend l'interface en ajoutant un membre avant « s_addr », ce programme plantera. Mais là, je pense qu'aucune personne en ce monde n'est assez insensée pour se risquer à ça. :-)

    Par contre, sur le plan sémantique, c'est intéressant parce que la structure « sin_addr », celle qui définit entièrement une adresse Internet, est réputée avoir été initialisée entièrement sans que l'on ait besoin d'auditer le reste du code ni d'aller examiner son contenu pour pouvoir l'affirmer.

    Les sockets en eux-mêmes restent une très bonne idée, surtout si on baigne dans l'esprit BSD. Mais il faut accepter qu'ils souffrent d'erreurs de jeunesse avec lesquels il faut composer. Par « erreur de jeunesse », j'entends « conception maladroite ». Il ne s'agit pas de bugs, bien sûr. Comme, globalement, il ne s'agit que de gérer les subtilités du C, je les trouve acceptables.

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Ok, j'ai compris une bonne partie du truc
    Cependant, si la struct in_addr n'aurait pas été la même (plusieurs variables), et que la valeure s_addr ne serait pas la prèmière valeure de cette struct, comment aurait-on fais ?

    On serait dans le cas de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    target_addr.sin_addr.s_addr = *((struct in_addr *) host_info->h_addr);
    Sauf que ca ne marcherait pas...
    Des reponses ?

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par ProgMac Voir le message
    Ok, j'ai compris une bonne partie du truc
    Cependant, si la struct in_addr n'aurait pas été la même (plusieurs variables), et que la valeure s_addr ne serait pas la prèmière valeure de cette struct, comment aurait-on fais ?
    On aurait re-vérifié le type du cast :-)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    target_addr.sin_addr.s_addr = *((struct in_addr *) host_info->h_addr);

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2011
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec l'apostrophe dans une requête
    Par mika0102 dans le forum VBA Access
    Réponses: 7
    Dernier message: 09/03/2019, 16h51
  2. problèmes avec "include file" pour une page asp
    Par chipsense dans le forum ASP
    Réponses: 1
    Dernier message: 02/09/2005, 15h22
  3. [Débutant] Problème avec les paramètres d'une proc stockée
    Par babulior dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 28/06/2005, 15h38
  4. Problèmes avec un TWebBrowser dans une DLL
    Par bellamyjc dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/01/2005, 22h35
  5. Problème avec un LIKE dans une procédure stockée
    Par Oluha dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/12/2004, 14h38

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