Encodage, décodage d’un entier en tableau de caractères

S’il vous plaît noter que ce n’est pas un devoir et j’ai fait une recherche avant de commencer ce nouveau fil. J’ai un magasin int dans un tableau de caractères?

Je cherchais une réponse, mais je n’ai obtenu aucune réponse satisfaisante dans le fil de discussion ci-dessus.

Voici mon exigence: je veux encoder mes données (disons un entier) dans un tableau d’octets, puis les transférer sur le réseau, puis les décoder à l’autre bout et les traiter.

Voici la partie encodage:

const int MAX=5; uint32_t a = 0xff00ffaa; char byte_array[1024]; // this is the array to be transferred over the network char buff[MAX]=""; sprintf(buff,"%4d",a); memcpy(byte_array,buff,4); // fill remaining stuff in the byte array and send it over the network 

Voici la partie décodage:

 const int MAX=5; char buff[MAX]=""; strncat(buff,byte_array,4) int i=atoi(buff); // Work with i 

Voici mes questions:

1) Le code ci-dessus est-il portable? Je suppose que c’est (corrigez-moi s’il vous plaît)

2) Maintenant, je veux encoder le tableau d’octets avec 3 octets (mais la taille entière est 4) c’est-à-dire que l’entier stocke 0x00ffaabb et je veux juste que le tableau d’octets ait ff int 0 index aa dans le 1er index et bb dans le 2ème index. Comment faire ça?

snprinf ne semble pas fonctionner ou peut-être me manque quelque chose.

Une personne qui a mis en œuvre un protocole réseau peut facilement m’aider. La logique de décodage fonctionnerait toujours, je suppose. ( strncat(buff,byte_array,3) suivi de l’ atoi fonction atoi ).

Voici ce que dit le protocole:

     -------- + -------- + -------- + -------- + -------------- ----------------
     | Version |  Longueur de 3 octets |  Trucs restants
     -------- + -------- + -------- + -------- + -------------- ----------------

La version est 1 octet, suivie de 3 octets de longueur du message.

J’espère pouvoir clarifier mon problème

Vous stockez en tant qu’ASCII, où vous devriez stocker les octets eux-mêmes.

Le codage devrait être quelque chose comme:

 uint32_t a = 0xff00ffaa; unsigned char byte_array[1024]; 

Remarquez comment j’ai fait en sorte que votre tableau cible ne soit pas signé, pour indiquer qu’il s’agit de “octets bruts” et non de caractères.

 byte_array[0] = a >> 24; byte_array[1] = a >> 16; byte_array[2] = a >> 8; byte_array[3] = a >> 0; 

Ceci sérialise la variable a dans les quatre premiers octets de byte_array utilisant l’ byte_array des octets big-endian, qui est en quelque sorte la valeur par défaut pour de nombreux protocoles de réseau.

Vous voudrez peut-être aussi voir ma réponse ici: question 1577161 .

1) c’est une sorte de travail puisque vous utilisez un tableau de caractères pour le transport, j’utiliserais personnellement un protocole binary. Si vous pouvez utiliser les 4 octets de votre variable, je jetterais un coup d’œil aux fonctions htonl / ntohl (elles sont sur pratiquement tous les Unix et Windows depuis W2K), sinon voir ci-dessous

2) avec un protocole binary, le codage serait

 uint32_t a = 0xff00ffaa; char byte_array[1024]; // this is the array to be transferred over the network // leave byte_array[0] for version byte // leave the high order byte in a since you want only the 3 lowest byte_array[1] = (char)((a & 0x00FF0000)>>16); byte_array[2] = (char)((a & 0x0000FF00)>>8); byte_array[3] = (char)(a & 0x000000FF); 

et le décodage serait

 uint32_t a = 0; a |= byte_array[1]<<16; a |= byte_array[2]<<8; a |= byte_array[3]; 

Ce que vous faites va sortinger du travail. Vous ne transférez pas les octets des données, vous transférez la valeur numérique des données. Par conséquent, un tampon de taille 5 est beaucoup trop petit pour les données que vous envoyez (0xFF00FFAA a une valeur numérique de 4278255530 – 10 octets).

Pour transférer les octets, vous devez procéder de la manière suivante (en supposant que little endian):

Encoder:

 char array[1024]; // outgoing network data int next = 0; array[next++] = value & 0xFF; array[next++] = (value >> 8) & 0xFF; array[next++] = (value >> 16) & 0xFF; array[next++] = (value >> 24) & 0xFF; 

Ces instructions suppriment les octets de la valeur et les affectent aux valeurs successives de votre tableau.

Décoder:

 char array[1024]; // incoming network data int next = 0; value = 0; value |= (int)*((unsigned char*)array)[next++]; value |= (int)*((unsigned char*)array)[next++] << 8; value |= (int)*((unsigned char*)array)[next++] << 16; value |= (int)*((unsigned char*)array)[next++] << 24; 

Ces instructions extraient les octets du tableau et les repoussent dans la valeur.

Si vous souhaitez essayer d’optimiser votre format de réseau sans transférer d’octets, vous pouvez éliminer une partie des données. Mais rappelez-vous que votre expéditeur et votre destinataire doivent savoir à quoi s’attendre - il faut donc que le type ou la longueur des éléments de données transmis soient communiqués.

Au moins, pour être portable, vous devriez penser à un ordre d’octets différent possible sur le codage.

Avez-vous vraiment besoin d’implémenter un nouveau protocole de messagerie réseau? Les logiciels NASC IPC ou Sun RPC ne vous conviennent-ils pas? Les deux sont suffisamment stables, la NASA est plus simple à démarrer, RPC semble plus disponible (oui, il est prêt à être utilisé et la bibliothèque est disponible pour la plupart des systèmes courants).

  • Pour RPC, essayez ‘man rpc’
  • Pour NASC IPC regardez ici

Peut-être devez-vous utiliser ce protocole avec un protocole existant, auquel cas, ignorez ma réponse.

Plutôt que de réinventer la roue, pourquoi ne pas utiliser la bibliothèque de tampons de protocole de Google pour faire ce travail? Plus simple, plus flexible et très efficace.

Utilisez XDR ( RFC 4506 ).

Ce que vous avez ne fonctionnera pas de la manière dont vous l’avez. Par exemple, a est 32 bits et dans votre exemple, vous définissez les bits de poids fort, ce qui signifie qu’il ne peut pas tenir dans un nombre à 4 chiffres avec votre instruction printf. (0xff00ffaa = 4278255530, ce qui représente plus de 4 chiffres) Je crois que le buffer sera saturé. Je pense que printf le convertira et débordera le champ, mais cela dépend de la manière dont votre compilateur / C implémente la fonction printf quand l’espace de mémoire tampon est insuffisant.

Pour l’instruction printf que vous avez, la valeur maximale que vous pouvez transmettre serait 9999 pour 4 caractères. De même, dans votre exemple de transfert de données avec le champ de longueur sur 3 octets, vous auriez une longueur maximale de 999. En théorie, votre longueur pourrait être de 1000 si vous ajoutez 1 à la longueur, mais le tampon que vous avez déclaré est de 1024. où la longueur maximale de la mémoire tampon dont vous auriez besoin serait de 1004 octets.

L’utilisation de caractères ASCII rend les messages / données transférables sur l’ensemble du système, mais cela se fait au désortingment de davantage de bande passante / espace, de temps de programmation et d’effort supplémentaire pour effectuer la conversion ASCII afin de transférer les données.

Il semble que vous ayez une bonne idée, mais il rest encore un peu de travail.

Il est probablement préférable d’utiliser un outil existant. Si vous ne pouvez pas – vous souciez-vous de l’endianisme (c’est-à-dire un protocole multi-plateforme?)

Sinon, vous pouvez simplement faire quelque chose comme …

 unsigned char msg[1024]; int writeIndex = 0; [...] int mynum = 12345; memcpy(msg + writeIndex , &mynum, sizeof mynum); writeIndex += sizeof mynum; 

et décoder

 //[...] also declare readIndex; memcopy(&mynum, msg + readIndex, sizeof mynum); readIndex += sizeof mynum; 

(vous pouvez remplacer la notion de msg + index par un pointeur de caractère non signé, bien que cela ait peu d’importance).

Utiliser une telle mémoire risque d’être plus lent, mais aussi plus lisible. Si nécessaire, vous pouvez implémenter un clone memcopy dans une fonction #define ou inline – il s’agit simplement d’une courte boucle d’assignations.

L’utilisation de la fonction atoi n’est justifiée que lorsque la chaîne que vous comptez décoder a été construite par votre propre code et pas plus de deux lignes plus haut. C’est-à-dire qu’il n’est utilisable que dans un code de type croquis.

Sinon, en particulier dans votre cas, lorsque les données arrivent du réseau, la fonction atoi ne peut pas être utilement utilisée pour effectuer le décodage, car elle ne fournit aucun mécanisme de traitement des erreurs utilisable et aucune protection contre les débordements (comportement indéfini en cas de débordement). La seule fonction qui puisse être utilisée de manière significative pour la conversion de chaîne en entier est une fonction du groupe strto... , strtol dans votre cas.