Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 4 sur 4
  1. #1
    Membre éprouvé
    Homme Profil pro Cyrill Gremaud
    Ingénieur systèmes et réseaux
    Inscrit en
    août 2005
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrill Gremaud
    Âge : 26
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Enseignement

    Informations forums :
    Inscription : août 2005
    Messages : 1 058
    Points : 448
    Points
    448

    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 :
    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 :
    typedef struct sockaddr_in SOCKADDR_IN;
    Rien de bien grave ici.

    Code :
    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 :
    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 :
    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
    Rédacteur/Modérateur
    Avatar de Melem
    Homme Profil pro Jessee Michaël Christian Edouard
    Ingénieur développement logiciels
    Inscrit en
    janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Nom : Homme Jessee Michaël Christian Edouard
    Âge : 28
    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 154
    Points
    8 154

    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 éprouvé
    Homme Profil pro Cyrill Gremaud
    Ingénieur systèmes et réseaux
    Inscrit en
    août 2005
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrill Gremaud
    Âge : 26
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Enseignement

    Informations forums :
    Inscription : août 2005
    Messages : 1 058
    Points : 448
    Points
    448

    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 :
    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 :
    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
    Rédacteur/Modérateur
    Avatar de Melem
    Homme Profil pro Jessee Michaël Christian Edouard
    Ingénieur développement logiciels
    Inscrit en
    janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Nom : Homme Jessee Michaël Christian Edouard
    Âge : 28
    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 154
    Points
    8 154

    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •