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 :

SOCKADDR_in vs sockaddr_in


Sujet :

Réseau C

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut SOCKADDR_in vs sockaddr_in
    bonjour,

    je me trouve confronté à un problème que je trouve bête mais n'arrive pas à le résoudre.

    Sous linux, je peux faire quelque chose du genre pour attribuer une addresse IP au champ de la structure sockaddr_in

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    const char* ip = "192.168.1.10";
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_addr.s_addr = inet_addr(ip);
    ceci fonctionne parfaitement sous linux mais sous windows cela ne fonctionne pas. En regardant dans le winsock.h, voici ce que l'on trouve.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct sockaddr_in SOCKADDR_IN;
    Rien de bien grave ici.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct sockaddr_in {
    	short	sin_family;
    	u_short	sin_port;
    	struct	in_addr sin_addr;
    	char	sin_zero[8];
    };
    Rien de bien méchant ici non plus. Mais si on regarde la structure in_addr, c'est ici que ça se complique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct in_addr {
    	union {
    		struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
    		struct { u_short s_w1,s_w2; } S_un_w;
    		u_long S_addr;
    	} S_un;
    J'ai essayé les 3 possibilités mais sans succès. au moment du bind j'ai une erreur. La seule qui fonctionne c'est si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SOCKADDR_IN addr;
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    Avec cette dernière méthode, ceci fonctionne mais impossible de trouver comment convertir mon const char* ip = "192.168.1.10"; pour pouvoir le mettre dans le champs d'adresse de la structure SOCKADDR_IN.

    merci de votre précieuse aide
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    C'est pas les fichiers d'en-tête qu'il faut décrypter mais la doc qu'il faut lire. Et ton code qui marche sous Linux devrait également marcher sous Windows. Sinon quelle erreur obtiens-tu exactement ? Enfin, utilise désormais winsock2.h. winsock.h c'est vieux comme le monde .

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    J'utilise déjà winsock2.h. L'erreur (errno) est : result is too large au moment du sendto et également au moment du bind. J'en conclu donc que l'erreur vient de l'un des paramètres présents dans ces fonctions, plus spécialement de la structure de définition de l'adresse, port etc. voici comment j'ai fais pour le bind et le sendto.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SOCKADDR_IN addr;
    		addr.sin_family = domain;
    		addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    		addr.sin_port = htons(port);
    		memset(&addr.sin_zero,'\0',sizeof(addr.sin_zero));
     
    int result = bind(fd, (SOCKADDR *)&addr, sizeof(addr));
    			printf("result = %i\n",result);
    			if(result == SOCKET_ERROR){
    				printf("bind - %s\n", strerror(errno));
    				system("pause");
    				exit(EXIT_FAILURE);
    			}
    Ce code fonctionne car addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY) fonctionne parfaitement mais impossible de spécifier une adresse ip de la forme "doted" dans ce champs. (du moins, je n'ai pas réussi).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int if_net_send(if_net_socket socket, const void *buffer, int bf_sz, void *dst_addr, int dst_addr_sz){
    	printf("buf size = %i, socket = %i\n",bf_sz,(SOCKET)socket);
     
    	SOCKADDR_IN *s = dst_addr;
    	printf("domain = %u, port = %i, zero = %s, ip = %lu\n",s->sin_family,s->sin_port,s->sin_zero,s->sin_addr.S_un.S_addr);
    	int result = sendto((SOCKET)socket, buffer, bf_sz, 0, (SOCKADDR *)dst_addr, dst_addr_sz);
    	printf("result = %i\n",result);
    	if(result < 0){
    		printf("sendto - %s\n", strerror(errno));
    		return (-1);
    	}
    	printf("message send : '%s' in file '%s'\n",__FUNCTION__,__FILE__);
    	return (0);
    }
    et rien de bien spécial pour le sendto. toujours le même problème.
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    L'erreur (errno) est : result is too large au moment du sendto et également au moment du bind. J'en conclu donc que l'erreur vient de l'un des paramètres présents dans ces fonctions, plus spécialement de la structure de définition de l'adresse, port etc
    Les fonctions de l'API WinSock (c'est-à-dire les sendto, bind, etc.) ne touchent jamais à errno. L'erreur vient d'ailleurs mais je ne peux pas t'en dire plus vu que je n'ai pas ton code en entier.

    Ce code fonctionne car addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY) fonctionne parfaitement mais impossible de spécifier une adresse ip de la forme "doted" dans ce champs.
    C'est inet_addr qu'il faut utiliser pour passer d'une chaîne IP à sa valeur en binaire. D'ailleurs, tu peux aussi utiliser inet_addr("0.0.0.0"), voire 0 tout simplement à la place de htonl(INADDR_ANY). Le résultat sera le même.

    Il faut également virer tes S_un.S_addr et les remplacer tout simplement par s_addr. Et qu'est-ce que le type if_net_socket ? Pourquoi le castes-tu en SOCKET. Si c'est le même type, pas besoin de cast. Sinon, ça voudra juste dire que ton code n'est pas bon et que ce n'est pas un cast qui arrangera cela. En gros, dans tous les cas, ce cast ne sert absolument à rien.

    Poster ton code complet pourrait peut-être également accélérer la résolution de ton problème.

Discussions similaires

  1. Différence entre sockaddr et sockaddr_in
    Par bebediddl dans le forum Réseau
    Réponses: 4
    Dernier message: 01/05/2010, 12h20
  2. struct sockaddr_in et gethostbyname
    Par j0o0 dans le forum C
    Réponses: 8
    Dernier message: 19/05/2007, 14h26

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