C ++ Sockets – Puis-je uniquement envoyer des caractères?

J’utilise des sockets synchronisés avec une fenêtre win32 et j’utilise les fonctions send () et recv () pour envoyer des données via Internet TCP;

Ce que je me demande, comment pourrais-je envoyer des entiers ou même ma propre classe / structure sur le socket TCP? parce que la fonction send () me permet seulement d’envoyer des caractères.

Aurais-je juste à envoyer des caractères et ensuite peut-être les convertir en entier avec atoi ()? ou si je voulais envoyer une structure de classe, est-ce que j’enverrais beaucoup de chaînes et les mettrais dans les variables, une par une.

Il n’envoie pas de caractères au sens textuel, il envoie des tableaux contigus d’octets, qu’il fait référence à un caractère *. Vous pouvez pointer sur les octets de n’importe quel type de valeur de cette façon, donc si vous voulez envoyer un int,

int A = 5; const char* pBytesOfA = (const char*)&A; int lengthOfBytes = sizeof(A); send(socket, pBytesOfA, lengthOfBytes, flags); 

Cela dépend de ce que vous voulez faire. Une possibilité simple est:

Supposons qu’un int ait 32 bits significatifs et que les valeurs négatives sont codées en complément à deux. Ensuite, vous pouvez envoyer un int sous forme de quatre chars :

 bool send_int(int fd, int i) { unsigned char buf[4]; buf[0] = (i >> 24) & 0xff; buf[1] = (i >> 16) & 0xff; buf[2] = (i >> 8) & 0xff; buf[3] = (i >> 0) & 0xff; return ((unsigned) send(fd, buf, sizeof buf, 0) == sizeof buf); } 

Du côté de la réception, vous devez lire quatre octets, puis combiner leurs valeurs afin qu’elles forment à nouveau un int .

Il existe de nombreuses autres possibilités pour coder les int et autres types de données sous forme de stream d’octets. Ce qui précède n’est qu’un exemple simple.

Plutôt que de le faire vous-même, utilisez des bibliothèques qui le font pour vous, comme Boost.Asio et Boost.Serialization .

Boost Asio est une bibliothèque qui remplace les sockets et fournit même une interface comme iostream C ++ et gérera pour vous l’envoi / la réception de types intégrés tels que int .

La sérialisation accrue vous permet de sérialiser facilement vos classes afin que vous puissiez les envoyer sur le réseau.

SI vous ne pouvez pas utiliser de bibliothèques supplémentaires, vous devrez envoyer les données manuellement sur des sockets simples. Assurez-vous de ne pas oublier d’utiliser les fonctions htons , ntohs , htonl et ntohl , htonl votre code ntohl lorsque les deux ordinateurs en communication utilisent ordre).

petit extrait:

 // sender: unsigned long to_send = 123; unsigned long to_send_n = htonl(to_send); // convert to network byte order send(send_socket, (const char*)(&to_send_n), sizeof(unsigned long), flags); // reciever: char recv_buf[sizeof(unsigned long)]; recv(recv_socket, recv_buf, sizeof(unsigned long)); //recieve number unsigned long recieved = ntohl(*((unsigned long*)recv_buf), flags); // convert back to host byte order 

Comme ces fonctions n’existent que pour les types non signés, vous serez limité aux types non signés.

AC (++) char n’est pas la même chose qu’un caractère . Un caractère est simplement un type entier avec au moins (et généralement exactement) 8 bits. Un caractère représente souvent un caractère ASCII (ou de nos jours, une unité de code UTF-8), mais il peut également représenter des données binarys arbitraires, comme c’est le cas avec send() et recv() .

Certains protocoles (par exemple, SMTP) supposent que les données sont du texte et peuvent modifier les données binarys contenant des octets tels que 0x0A (saut de ligne) ou 0x00 (terminateur de chaîne C). Dans ce cas, vous devez utiliser un codage binary en texte tel que Base64. Mais cela ne devrait pas être un problème si vous travaillez directement avec TCP.