Je développe une application serveur-client où le client fonctionnera sous Windows et le serveur probablement sous Linux. Peut-être que je porterai plus tard le client sur Mac et Linux, mais pas encore.
Tous les ordinateurs personnels fonctionnent de nos jours sur le petit-boutien. J'ai googlé un moment, mais je n'ai pas vraiment pu trouver une liste d'appareils fonctionnant sur big-endian. Pour autant que je sache, certaines puces Motorola utilisent encore du big-endian et peut-être certains téléphones (je ne prévois pas de porter l'application sur les smartphones, donc cela n'a pas d'importance pour moi). Alors, pourquoi réorganiserais-je les octets de chaque entier, chaque court, chaque flottant, double, etc., pour la lecture et l' écriture , alors que je sais déjà que le serveur et le client s'exécutent sur little-endian?
C'est juste un travail inutile à faire. Donc, ma question est: puis-je ignorer l'endianité en toute sécurité et envoyer simplement des données de petit endian? Quels sont les inconvénients?
la source
Réponses:
Ce n'est inutile que si vous pouvez garantir que votre code fonctionnera toujours sur des architectures peu endiennes. Si vous avez l'intention qu'il ait une longue durée de vie, cela vaut la peine de faire l'effort supplémentaire pour éviter de perturber le code éprouvé dans une décennie à partir de ce moment où une architecture big-endian est devenue le "in" et que vous trouvez que c'est un bon marché pour ton application.
Il existe un ordre d'octets standard du réseau. C'est du big-endian, mais rien ne dit que vous devez le respecter lors de la conception de votre protocole. Si vous savez à l'avance que la majorité des systèmes exécutant votre code seront peu endiens et que les performances sont critiques, déclarez que le "tkausl standard byte ordering" et allez-y. Là où vous appelez normalement
htons()
pour mettre les choses dans l'ordre dont vous avez besoin, écrivez une macro appeléehtots()
qui se compile conditionnellement sur rien sur les architectures little-endian et fait le réarrangement sur big-endian.Maintenir le code pour effectuer les conversions entrantes et sortantes n'est pas vraiment un gros effort. Si vous avez un très grand nombre de messages, trouvez un moyen de les exprimer et écrivez un programme pour générer les conversions entrantes et sortantes.
la source
when designing your protocol
est important, car il dit également implicitement que cette option n'existe que lors de la conception d'un nouveau protocole et non lors de la mise en œuvre d'un protocole existant. Et mentionner la nécessité d'unehtots
(et vraiment d'une famille entière de fonctions), indique également clairement que le choix d'un ordre d'octets différent n'est pas quelque chose que l'on fait pour rendre le code plus simple, mais cela pourrait le rendre légèrement plus rapide.htole32()
,htole16()
,le16toh()
, etc., les fonctions disponibles. Le fichier à inclure pour les faire déclarer est malheureusement encore moins standard:<endian.h>
ou<sys/types.h>
selon la plateforme.C'est ton protocole.
Vous ne pouvez pas l'ignorer en toute sécurité. Mais vous pouvez l'étiqueter en toute sécurité. Vous contrôlez le client et le serveur. Vous contrôlez le protocole. N'est-il pas logique de ne pas se soucier de savoir si c'est du big-endian ou du little-endian tant que vous savez si les deux parties sont d'accord?
Cela signifie des frais généraux. Maintenant, vous devez marquer votre endianité d'une manière ou d'une autre. Faites cela, et je peux le lire sur n'importe quoi.
Si vous ne voulez pas de surcharge de données et que votre CPU s'ennuie et cherche quelque chose à faire, alors conformez-vous .
la source
Il y a deux interprétations de cela:
Si vous concevez vos applications / protocoles pour toujours envoyer 1 little-endian, alors vous n'ignorez pas l'endianess.
Si vous concevez vos applications / protocoles pour envoyer / recevoir quel que soit l'endianess natif, alors ils fonctionneront tant que vous exécuterez vos applications sur des plates-formes avec la même endianess native.
Est-ce "sûr" 2 ? A vous de juger! Mais il existe certainement des plates-formes matérielles communes qui utilisent le petit-boutien, le gros-boutien ou ... le bi-boutien.
Référence:
L'inconvénient évident d'ignorer l'endianess est que si vous / vos utilisateurs devez exécuter vos applications / protocoles entre des plates-formes ayant une endianess native différente, alors vous avez un problème. Les applications s'arrêteront et vous devrez les modifier pour résoudre le problème. Et gérer les problèmes de compatibilité des versions, etc.
De toute évidence, la plupart des plates-formes de génération actuelles sont nativement peu endiennes, mais 1) certaines ne le sont pas et 2) nous ne pouvons que deviner ce qui se passera à l'avenir.
1 - Toujours ... y compris sur des plateformes natives big-endian.
2 - En effet, que signifie «sûr»? Si vous nous demandez de prédire l'orientation future des plates-formes matérielles ... Je crains que ce ne soit pas objectivement responsable.
la source
L'endianisme n'est pas la seule considération. Il y a la taille des entiers, il y a un paquet de structures que vous voudrez peut-être envoyer ou recevoir, etc.
Vous pouvez ignorer tout cela. Personne ne peut te forcer. D'un autre côté, le moyen sûr et fiable est de documenter un format externe, puis d'écrire du code qui lira ou écrit correctement le format externe, quels que soient votre processeur, votre langage de programmation et l'implémentation de votre langage de programmation.
Ce n'est généralement pas beaucoup de code. Mais cela a un énorme avantage: les personnes qui lisent votre code ne soupçonneront pas que vous êtes ignorant, ne savent rien sur l'échange de données externes et écrivent du code qui ne peut généralement pas faire confiance.
la source
La pile de mise en réseau BSD standard en C a la fonctionnalité
hton
/ntoh
(network-to-host
/host-to-network
) qui s'étend aux no-ops sur les machines natives du réseau (big endian). Vous auriez besoin de vos propres homologues pour ceux-ci pour le scénario dans lequel l'ordre des octets natif du réseau est peu endian.C'est la manière robuste de le faire.
Ce ne serait pas conventionnel, mais je n'y vois rien de mal. Les ordinateurs en réseau obtiennent toujours des flux d'octets et ils doivent s'entendre sur des protocoles sur la façon d'interpréter ces octets. Cela n'en fait qu'une partie.
la source
Différents protocoles utilisés pour transmettre des données entre serveurs utilisent de petits nombres endiens:
Voir https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats , pour plus de détails sur les différents formats dont certains ont des nombres en petit bout et certains ont des nombres en gros.
Il n'y a absolument rien de mal à utiliser un protocole basé sur de petits nombres endiens. Une grande machine endienne est tout aussi capable de lire de petits nombres endiens qu'une petite machine endienne peut lire de grands nombres endiens. Beaucoup de gens l'ont fait spécifiquement pour éviter le coût de calcul supplémentaire du décodage des nombres big-endian sur les petites machines endian.
Si vous construisez votre protocole sur l'un de ces protocoles existants, vous n'avez même pas à vous soucier du problème vous-même, il est déjà pris en charge. Lorsque vous décidez d'exécuter votre code sur une plate-forme big-endian, les bibliothèques qui implémentent ces protocoles se chargeront automatiquement de s'assurer que vous décodez les valeurs correctement.
la source
Un exemple d'un grand système endian est le MIPS utilisé dans les routeurs. ARM et MIPS sont commutables par endian, mais souvent MIPS est un gros endian car il facilite le matériel réseau (la partie la plus importante d'un mot est la partie que vous recevez en premier et peut prendre une décision de routage avant d'avoir reçu le reste de le mot plutôt que d'avoir à mettre le mot entier en mémoire tampon).
Cela dépend donc de ce que vous entendez par `` Linux '', mais si vous souhaitez exécuter votre application serveur sur un système plus petit comme un routeur exécutant OpenWRT, vous devrez peut-être envisager un support endian important.
Comme d'habitude, faire des hypothèses simplificatrices est une optimisation parfaitement sensée jusqu'à ce que vous frappiez quelque chose qui ne correspond pas aux hypothèses. Vous seul pouvez dire à quel point il serait douloureux de les dérouler si jamais vous rencontriez un tel problème.
la source
Je ne pense pas que les réponses soient assez précises. Selon Wikipedia, l' endianité est l'ordre des octets comprenant un mot.
Permet de prendre 4 octets et de les interpréter comme un entier. Dans un petit système endian, les octets seront interprétés de droite à gauche, et vice-versa sur un grand système endian. De toute évidence, il est important de s'entendre sur la fin de l'interprétation d'un int.
Permet de zoomer un peu sur les protocoles réseau modernes qui pourraient utiliser json ou xml. Aucun de ces formats ne transférera un entier sous forme de 4 octets. Ils transfèrent les données sous forme de texte qui sera analysé en tant qu'intérieur sur le côté récepteur.
Donc, à la fin, l'endianité n'a pas d'importance lors de l'utilisation de json ou xml. Nous devons encore utiliser big endian pour les en-têtes tcp, c'est pourquoi il est appelé ordre des octets du réseau, mais la plupart des programmeurs n'ont pas besoin de jouer avec ceux-ci quotidiennement.
L'encodage le plus largement utilisé aujourd'hui est utf-8 qui est également immunisé contre les problèmes d'endianisme .
Je dirais donc oui. Il est sûr d'ignorer l'endianité lors de l'utilisation de formats basés sur du texte transférés à l'aide d'utf-8.
la source
Les grands systèmes endiens semblent en voie de disparition. Beaucoup des unix traditionnels utilisaient du big endian mais ils sont en déclin depuis des années en faveur de linux sur x86.
le bras est bi-endien mais la variante big endian semble être rarement vue.
mips existe dans les deux variantes. Afaict la variante big endian est principalement observée sur les applications de mise en réseau (pour des raisons historiques, les protocoles Internet utilisent généralement le big endian).
ppc était traditionnellement un gros endian avec certaines parties prenant en charge les deux endians mais IBM semble maintenant pousser le petit mode endian pour le ppc 64 bits (ils ont récemment poussé les ports ppc64el dans Debian et Ubuntu).
sparc est normalement gros endian mais semble encore être en déclin.
Si vous implémentez un protocole existant, vous devez évidemment suivre ses spécifications. Si vous voulez que l'IETF bénisse votre nouveau protocole, le big endian sera probablement plus facile, car c'est ce qu'ils utilisent déjà dans leurs protocoles existants, mais IMO pour une nouvelle conception de protocole "greenfield", peu endian est le chemin à parcourir.
Vous pouvez soit mettre des macros depuis le début qui seront sans opération sur les petits systèmes endiens, soit vous ne pouvez pas déranger jusqu'à / à moins que vous ayez besoin de porter sur un grand système endien.
la source