caster en char * une structure

caster en char * une structure - C - Programmation

Marsh Posté le 31-07-2006 à 15:27:23    

bonjour,
je dispose d'un client et un serveur tcp et je dois envoyer une structure de données avec beaucoup de champs du client ->serveur. Alors pour cela je rempli les champs de ma struture au niveau client et je l'envoie avec la primitive send vers mon serveur. mais j'ai du mal à faire le castage en char * de ma struture  du coté client comme du coté serveur. je demande de l'aide.
Merci.

Reply

Marsh Posté le 31-07-2006 à 15:27:23   

Reply

Marsh Posté le 31-07-2006 à 16:40:31    

1) ton code
2) dans ta structure tu as des pointeurs ?

Reply

Marsh Posté le 31-07-2006 à 16:54:15    

ham222 a écrit :

bonjour,
je dispose d'un client et un serveur tcp et je dois envoyer une structure de données avec beaucoup de champs du client ->serveur. Alors pour cela je rempli les champs de ma struture au niveau client et je l'envoie avec la primitive send vers mon serveur. mais j'ai du mal à faire le castage en char * de ma struture  du coté client comme du coté serveur. je demande de l'aide.
Merci.


Tu as une structure contenant des champs, style

struct {
char nom[10];
char prenom[10];
int age;
} info;


 
En lisant ton titre, on a l'impression que tu envoies directement "info" par send. Or send veut l'adresse de la variable à envoyer et non la variable elle-même. Il te faut donc passer à send l'adresse de info. Style

send(socket, &info, sizeof(info), 0)


Là, t'auras aucun pb.  
 
La question de bjone est importante car dans mon exemple de structure, toutes les infos sont contigües. Donc en partant de l'adresse de "info" qui correspond au premier octet de "nom" et en envoyant octet par octet l'ensemble complet de la structure sur la socket, toutes les infos arriveront de l'autre coté. En revanche, un pointeur est une indirection. C'est à dire que si ta structure contient un pointeur dont le contenu (par exemple alloué par "malloc" ) se trouve 40km plus loin, celui-ci se trouve hors de ta structure et ne sera pas envoyé sur la socket. Tu ne réceptionnera de l'autre coté qu'une adresse sans signification. Ce problème se retrouve quand on veut copier des structures avec "memcpy()"...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 31-07-2006 à 17:00:38    

Merci Sve@r pour cette explication (et [:drapal] du coup)

Reply

Marsh Posté le 31-07-2006 à 17:04:58    

Sve@r a écrit :

Tu as une structure contenant des champs, style

struct {
char nom[10];
char prenom[10];
int age;
} info;


 

send(socket, &info, sizeof(info), 0)


Là, t'auras aucun pb.  


Sauf que le format des données sur le réseau n'est pas standard, et qu'au bout, si la machine n'est pas strictement identique, ça ne fonctionnera pas. (endianness, alignement, taille des types...). Faut pas balancer n'importe quoi sur le réseau...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-07-2006 à 17:12:56    

c'est vrai aussi. dumoins ce qui envoyé sur le réseau est standard, mais avec deux exécutables compilés par un compilateur différent peut provoquer des alignements différents ou sur un cpu dfférent ça peut effectivement provoquer un pb d'endianness.
 
mais bon on peut supposer qu'il a pris une convention et qu'il s'y tiens.

Reply

Marsh Posté le 01-08-2006 à 10:17:21    

_darkalt3_ a écrit :

Merci Sve@r pour cette explication (et [:drapal] du coup)

Citation :

Sauf que le format des données sur le réseau n'est pas standard, et qu'au bout, si la machine n'est pas strictement identique, ça ne fonctionnera pas. (endianness, alignement, taille des types...). Faut pas balancer n'importe quoi sur le réseau...



La remarque de Emmanuel est importante. En effet, le format d'un int (et autres types assimilés comme short ou long) peut changer entre les systèmes. Dans l'un, il sera codé de gauche à droite, (style 10=0x00a0) et dans l'autre il sera codé de droite à gauche (style 10=0x0a00). Si tu travailles en environnements hétérogènes et que tu balances ta structure comme ça, tu risques d'avoir n'importe quoi dans le champ "age" de l'autre coté.
De plus, certains compilateurs optimisent les structures en rajoutant des octets bidons entre les champs pour aligner la structure sur un mot machine. Si la structure de l'autre coté n'est pas exactement au même format, tu obtiens n'importe quoi.
 
Pour résumer, si tu veux juste t'amuser à créer un programme pour apprendre les sockets tu peux t'en tenir à mon exemple initial. Mais si tu travailles pour un réel et important projet, alors il te faut  

  • prendre chaque champ un à un
  • si le champ est de type "int" ou assimilé, faut le transformer en "entier réseau" avec "htons()" ou "htonl()" selon le type
  • envoyer l'info sur la socket

De l'autre coté, il te faut

  • récupérer l'info
  • si c'est un "int" ou assimilé faut le convertir en "entier local" avec "ntohs()" ou "ntohl()" selon le type
  • stocker l'info dans le champ qui va bien de ta structure


Cours sur les sockets Unix ici: http://fr.lang.free.fr/cours/SocketCsyst_v1.0.pdf


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-08-2006 à 10:18:30    

:jap:

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed