Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Réseau
Réseau Forum d'entraide sur la programmation réseau en C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 19/10/2012, 13h26   #1
cyrill.gremaud
Membre éprouvé
 
Homme Cyrill Gremaud
Ingénieur systèmes et réseaux
Inscription : août 2005
Messages : 1 031
Détails du profil
Informations personnelles :
Nom : Homme Cyrill Gremaud
Âge : 24
Localisation : Suisse

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

Informations forums :
Inscription : août 2005
Messages : 1 031
Points : 459
Points : 459
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...
cyrill.gremaud est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2012, 18h02   #2
Melem
Rédacteur/Modérateur
 
Avatar de Melem
 
Homme Jessee Michaël Christian Edouard
Ingénieur développement logiciels
Inscription : janvier 2006
Messages : 3 660
Détails du profil
Informations personnelles :
Nom : Homme Jessee Michaël Christian Edouard
Âge : 27
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 660
Points : 8 525
Points : 8 525
Envoyer un message via MSN à Melem
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 .
Melem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/10/2012, 07h50   #3
cyrill.gremaud
Membre éprouvé
 
Homme Cyrill Gremaud
Ingénieur systèmes et réseaux
Inscription : août 2005
Messages : 1 031
Détails du profil
Informations personnelles :
Nom : Homme Cyrill Gremaud
Âge : 24
Localisation : Suisse

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

Informations forums :
Inscription : août 2005
Messages : 1 031
Points : 459
Points : 459
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...
cyrill.gremaud est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/10/2012, 11h14   #4
Melem
Rédacteur/Modérateur
 
Avatar de Melem
 
Homme Jessee Michaël Christian Edouard
Ingénieur développement logiciels
Inscription : janvier 2006
Messages : 3 660
Détails du profil
Informations personnelles :
Nom : Homme Jessee Michaël Christian Edouard
Âge : 27
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 660
Points : 8 525
Points : 8 525
Envoyer un message via MSN à Melem
Citation:
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.

Citation:
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.
Melem est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 14h38.


 
 
 
 
Partenaires

Hébergement Web