2017-05-18 2 views
0

Supposons que nous écrivions une application réseau C++ à l'aide de sockets UDP. Nous avions besoin de passer un pas si petit paquet de données, nous avons donc utilisé ce type de structure, en veillant à l'ordre des octets est le réseau un:Alternative portable pour les structures compactes avec un membre de groupe flexible

struct [[gnu::packed]] datagram { 
    uint64_t timestamp; 
    uint8_t type; 
    uint32_t temperatures[60]; // whatever, just an example 
    uint8_t raw_data[]; 
}; 

Nous utilisions GNU GCC, donc nous avons profité de non standard caractéristiques ++ C tels que membre

  • flexible de tableau
  • Structure emballée

nous avions besoin d'une structure emballée puisque nous ne voulons pas de rembourrage entre les deux, car cela pourrait être architecte uré-dépendante, et notre programme de réseau peut fonctionner sur différentes architectures.

Ensuite, après un an, il se peut que nous devions prendre en charge un compilateur non-GCC, qui ne les prend pas en charge. Est-il possible de faire cela en C++ standard?

Bien sûr, je sais que nous pourrions simplement utiliser un uint8_t buffer[SOME_SIZE] et memcpy chaque partie du datagramme, mais cela semble être un excellent moyen de créer du code horrible, vraiment moche.

+4

Recherchez et utilisez une bibliothèque de sérialisation. Ce problème a été résolu à plusieurs reprises, pourtant les gens insistent pour le faire encore et encore parce qu'aucune des solutions n'est bonne. – nwp

Répondre

3

[[gnu::packed]] est une manière terrible de faire la sérialisation entre les architectures arbitraires. Il y a encore des machines big-endian. La bonne façon de procéder est de définir un format de sérialisation en termes d'octets, puis de convertir entre un flux d'octets (vers ou depuis le socket UDP) et une structure bien organisée.

Il existe de nombreuses bibliothèques qui rendent cela simple. Nous utilisons protobuf au travail; un employeur précédent avait une solution brassée à la maison. (Notez qu'une demande de recommandation pour une telle bibliothèque est hors-sujet explicite pour Stack Overflow.)

+0

Bien sûr, de sorte que vous pouvez conserver les données dans la structure dans l'ordre des octets du réseau. Edité le PO. – marmistrz