Endianness et programmation de sockets en C

Je crée un programme qui communique avec certains moniteurs patient à l’aide de sockets C. J’utilise des sockets sans connexion (UDP) pour communiquer avec l’appareil. Mais il y a un décalage d’appariement entre mon ordinateur et mon appareil et jusqu’à présent, je le faisais pour obtenir une réponse d’parsing du moniteur patient:

recvfrom(int socket, char *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len); 

Ensuite, je transformais le tampon directement en structure et utilisais les commandes ntohs et ntohl pour modifier l’ordre des octets, par exemple:

 struct A * a = (struct A *)buffer; Struct A b; b.v1 = ntohs(a->v1); b.v2 = ntohl(a->v2); 

Après avoir lu quelques exemples sur Internet, j’ai compris que cela pouvait être une mauvaise approche en raison du remplissage dépendant du compilateur. Mais je n’en suis pas sûr. J’ai besoin d’un moyen simple pour décompresser un tampon dans une structure en C avec les endiannes correctes. La structure que je reçois peut être de longueur imprévisible et peu complexe également. J’ai besoin d’une approche rapide et facile pour faire le désordre.

Je ne contrôle pas l’expéditeur. L’expéditeur est dans l’ordre des octets du réseau. Ma question est la suivante: – est-il sûr de lancer un tampon sur une structure, puis d’utiliser ntohs et ntohl sur cette structure préfixée pour en faire une réplique d’ordre octet par hôte de cette structure? Est-ce une approche plus rapide? Si non, alors quelle peut être l’approche la plus rapide?

Tout d’abord, comme a est a pointeur, votre code devrait au moins faire cela …

 b.v1 = ntohs(a->v1); b.v2 = ntohl(a->v2); 

Deuxièmement, la réponse dépend des circonstances et des spécifications du moniteur patient. Qui écrit le code pour le moniteur patient? Y at-il une spécification pour cela? Quelle architecture de machine utilise-t-elle (au cas où vous le sachiez), utilisez-vous un seul modèle ou existe-t-il plusieurs versions du moniteur – pouvez-vous changer le moniteur, etc.

Je vais supposer que vous ne pouvez pas changer le moniteur, et que l’ordre des octets est documenté quelque part – et que vous devrez peut- être créer vos propres routines de décompression / emballage, en effectuant l’adressage d’octets et la manipulation de bits – c’est-à-dire que si vous savez que le format correspond exactement à celui de la commande “network” – et que le remplissage des structures est le même dans le tampon réseau.

Donc, quelque chose comme

 void unpack(struct *b, unsigned char *buffer) { b->v1 = (buffer[0] <<8)|(buffer[1]);  b->v2 = (buffer[2] <<24)|(buffer[3] <<16)|(buffer[4] <<8)|(buffer[5]); etc.... } 

ou comme ça si vous préférez vous-même;

 void unpack(struct *b, unsigned char *buffer) { b->v1 = ntohs(buffer+0);  b->v2 = ntohl(buffer+2); etc.... } 

Toutefois, si vous contrôlez le code du moniteur, l'utilisation d'un outil tel que les tampons de protocole vous évitera toute la complexité de la manipulation de bits et vous préoccupera des ordres d'octets ...