Comment envoyer un tableau d’entiers sur TCP en C?

Je suis porté à croire que write() ne peut envoyer que des tampons de données d’octet (c’est-à-dire un caractère signé), alors comment envoyer un tableau d’entiers longs en utilisant la fonction C write() de la bibliothèque sys / socket.h?

Évidemment, je ne peux pas convertir ou convertir longtemps en caractères car tout nombre supérieur à 127 serait mal formé.

J’ai jeté un coup d’oeil à la question, comment décomposer un tableau entier en un tableau d’octets (codage en pixels) , mais je ne pouvais pas le comprendre. S’il vous plaît, quelqu’un pourrait-il l’inscrire un peu si c’est ce que je cherche?

Question de suivi:

Pourquoi ai-je des résultats étranges lorsque je lis un tableau d’entiers à partir d’un socket TCP?

le prototype pour write est:

 ssize_t write(int fd, const void *buf, size_t count); 

ainsi, même s’il écrit en unités d’octets, il peut prendre un pointeur de tout type. Passer un int* ne posera aucun problème.

MODIFIER:

Je recommanderais cependant que vous envoyiez également la quantité d’entiers que vous prévoyez d’envoyer en premier afin que le récepteur sache combien il faut lire. Quelque chose comme ceci (vérification d’erreur omise pour des raisons de brièveté):

 int x[10] = { ... }; int count = 10; write(sock, &count, sizeof(count)); write(sock, x, sizeof(x)); 

REMARQUE: si le tableau provient de la mémoire dynamic (comme vous l’avez fait avec malloc ed), vous ne pouvez pas utiliser sizeof sur celui-ci. Dans ce cas, le nombre serait égal à: sizeof(int) * element_count

MODIFIER:

Comme Brian Mitchell l’a noté, vous devrez probablement également faire attention aux problèmes d’ endianisme . C’est le cas lors de l’envoi de n’importe quelle valeur multi-octets (comme dans le décompte recommandé par I ainsi que chaque élément du tableau). Ceci est fait avec les fonctions: htons / htonl et ntohs / ntohl .

Ecrire peut faire ce que vous voulez, mais il y a certaines choses à prendre en compte:

1: Vous pouvez obtenir une écriture partielle qui n’est pas sur une frontière int. Vous devez donc être prêt à gérer cette situation.

2: Si le code doit être portable, vous devez convertir votre tableau en une endianess spécifique ou encoder la endianess dans le message.

Oui, vous pouvez simplement transformer un pointeur de votre tampon en pointeur sur char et appeler write() avec cela. Transtyper un pointeur sur un type différent en C n’affecte pas le contenu de la mémoire pointée; il indique simplement l’intention du programmeur que le contenu de la mémoire à cette adresse soit interprété différemment.

Assurez-vous simplement que vous fournissez à write() la taille correcte en octets de votre tableau – ce serait le nombre d’éléments multiplié par sizeof (long) dans votre cas.

Le moyen le plus simple d’envoyer un seul int (en supposant des entiers de 4 octets) est:

 int tmp = htonl(myInt); write(socket, &tmp, 4); 

où htonl est une fonction qui convertit l’int en ordre des octets du réseau . (De même, lorsque vous lisez à partir du socket, la fonction ntohl peut être utilisée pour reconvertir en ordre d’octet hôte.)

Pour un tableau d’ints, vous voudrez d’abord envoyer le nombre de membres du tableau sous forme d’int (dans l’ordre des octets du réseau), puis envoyer les valeurs int.

Il serait préférable d’avoir la fonctionnalité sérialiser / désérialiser dans votre programme client / serveur.

Chaque fois que vous souhaitez envoyer des données, sérialisez-les dans un tampon d’octets et envoyez-les sur TCP avec un nombre d’octets.

Lors de la réception de données, déssérialisez les données du tampon sur votre propre interprétation.

Vous pouvez interpréter le tampon d’octets sous n’importe quelle forme. Il peut contenir un type de données de base, des objects, etc.

Assurez-vous juste de vous occuper de l’endianesse et de l’alignement.

Déclarez un tableau de caractères. À chaque emplacement du tableau, stockez des nombres entiers, pas des caractères. Ensuite, vous envoyez juste ça.

Par exemple:

 char tcp[100]; tcp[0] = 0; tcp[1] = 0xA; tcp[2] = 0xB; tcp[3] = 0xC; . . // Send the character array write(sock, tcp, sizeof(tcp)); 

Je pense que ce que vous devez trouver ici est un protocole .

Supposons que votre tableau entier est:

 100, 99, 98, 97 

Au lieu d’écrire les données directement dans le tampon, je «sérialiserais» le tableau en le transformant en représentation sous forme de chaîne. La chaîne pourrait être:

 "100,99,98,97" 

C’est ce qui serait envoyé sur le fil. Du côté du destinataire, vous scindiez la chaîne par des virgules et reconstruisez le tableau.

Ceci est plus standardisé, est lisible par l’homme et signifie que les gens n’ont pas à penser aux ordres hi / lo byte et à d’autres choses stupides.

// Sarcasme

Si vous travailliez en .NET ou Java, vous l’encoderiez probablement en XML, comme ceci:

 100999897 

🙂