Estoy desarrollando una aplicación servidor-cliente donde el cliente se ejecutará en Windows y el servidor probablemente en Linux. Tal vez luego transfiera el cliente a Mac y Linux, pero aún no.
Todos los equipos domésticos en estos días funcionan con little-endian. Busqué en Google por un tiempo, pero realmente no pude encontrar una lista de dispositivos que se ejecutan en big-endian. Hasta donde sé, algunos chips Motorola todavía usan big-endian y tal vez algunos teléfonos (no planeo portar la aplicación a teléfonos inteligentes, así que esto no me importa). Entonces, ¿por qué reorganizaría los bytes de cada entero, cada corto, cada flotante, doble, etc., para leer y escribir , cuando ya sé que tanto el servidor como el cliente se ejecutan en little-endian?
Eso es solo un trabajo innecesario que hacer. Entonces, mi pregunta es: ¿puedo ignorar con seguridad el endianness y simplemente enviar datos little-endian? ¿Cuales son las desventajas?
fuente
Respuestas:
Solo es innecesario si puede garantizar que su código siempre se ejecutará en arquitecturas little-endian. Si tiene la intención de que tenga una larga vida, vale la pena el esfuerzo adicional para evitar perturbar el código bien probado dentro de una década, cuando alguna arquitectura big-endian se ha convertido en lo "in" y considera que es un buen mercado para su aplicación.
Hay un orden de bytes estándar de red. Es big-endian, pero nada dice que tenga que cumplirlo al diseñar su protocolo. Si sabe de antemano que la mayoría de los sistemas que ejecutan su código serán poco endian y el rendimiento es crítico, declare que el "orden de bytes estándar tkausl" y vaya con él. Donde normalmente llamaría
htons()
para poner las cosas en el orden que necesita, escriba una macro llamadahtots()
que compila condicionalmente nada en arquitecturas little-endian y hace la reorganización en big-endian.Mantener el código para realizar las conversiones entrantes y salientes no es realmente un gran esfuerzo. Si tiene una gran cantidad de mensajes, busque la forma de expresarlos y escriba un programa para generar las conversiones entrantes y salientes.
fuente
when designing your protocol
es importante, porque también dice implícitamente que esta opción solo existe cuando se diseña un nuevo protocolo y no cuando se implementa algún protocolo existente. Y al mencionar la necesidad de unahtots
(y realmente una familia completa de funciones), también deja en claro que elegir un orden de bytes diferente no es algo que se hace para simplificar el código, pero podría hacerlo un poco más rápido.htole32()
,htole16()
,le16toh()
, etc., funciones disponibles también. Lamentablemente, el archivo que se debe incluir para declararlos es aún menos estándar:<endian.h>
o<sys/types.h>
depende de la plataforma.Es tu protocolo.
No puedes ignorarlo con seguridad. Pero puedes etiquetarlo con seguridad. Usted controla el cliente y el servidor. Tú controlas el protocolo. ¿No tiene sentido no preocuparse si es big-endian o little-endian siempre y cuando sepas si ambas partes están de acuerdo?
Esto significa gastos generales. Ahora tienes que marcar tu endianness de alguna manera. Haz eso y puedo leerlo en cualquier cosa.
Si no desea una sobrecarga de datos, y su CPU está aburrida y busca algo que hacer, entonces conéctese .
fuente
Hay dos interpretaciones de eso:
Si diseñas tus aplicaciones / protocolos para siempre 1 Enviar ascendente hacia la izquierda, entonces usted no está haciendo caso omiso endianess.
Si diseña sus aplicaciones / protocolos para enviar / recibir cualquiera que sea la endianess nativa, funcionarán siempre que ejecute sus aplicaciones en plataformas con la misma endianess nativa.
¿Es eso "seguro" 2 ? ¡Eso es para que juzgues! Pero ciertamente hay plataformas de hardware comunes que usan little-endian, big-endian o ... bi-endian.
Referencia:
La desventaja obvia de ignorar la endianess es que si usted / sus usuarios necesitan ejecutar sus aplicaciones / protocolos entre plataformas con diferente endianess nativa, entonces tienen un problema. Las aplicaciones se interrumpirán y deberá cambiarlas para solucionar el problema. Y lidiar con problemas de compatibilidad de versiones, etc.
Claramente, la mayoría de las plataformas de generación actual son nativamente little endian, pero 1) algunas no lo son, y 2) solo podemos adivinar lo que sucederá en el futuro.
1 - Siempre ... incluso en plataformas que son nativas big-endian.
2 - De hecho, ¿qué significa "seguro"? Si nos pide que pronostiquemos la dirección futura de las plataformas de hardware ... me temo que no se puede responder objetivamente.
fuente
Endianness no es la única consideración. Existe el tamaño de los enteros, hay un paquete de estructuras que es posible que desee enviar o recibir, y así sucesivamente.
Puedes ignorar todo esto. Nadie puede forzarte. Por otro lado, la forma segura y confiable es documentar un formato externo y luego escribir código que lea o escriba el formato externo correctamente, sin importar cuál sea su procesador, su lenguaje de programación y la implementación de su lenguaje de programación.
Por lo general, no es mucho código. Pero tiene un gran beneficio: las personas que leen su código no sospecharán que no tiene idea, no saben nada sobre el intercambio de datos externos y escriben código en el que generalmente no se puede confiar.
fuente
La pila de red BSD estándar en C tiene la funcionalidad
hton
/ntoh
(network-to-host
/host-to-network
) que se expande a no-ops en máquinas nativas de red (big endian). Necesitaría sus propias contrapartes para el escenario en el que el orden de bytes nativo de la red es poco endian.Esa es la forma sólida de hacerlo.
Sería poco convencional, pero no veo nada de malo en ello. Las computadoras en red siempre obtienen pruebas y necesitan acordar protocolos sobre cómo interpretar esos bytes. Esto es solo parte de eso.
fuente
Varios protocolos utilizados para transmitir datos entre servidores usan pequeños números endian:
Consulte https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats , para obtener detalles sobre varios formatos, algunos de los cuales tienen números little-endian y otros tienen números big-endian.
No hay absolutamente nada de malo en usar un protocolo basado en pequeños números endianos. Una máquina endian grande es tan capaz de leer números endian pequeños como una máquina endian pequeña puede leer números endian grandes. Muchas personas lo han hecho específicamente para evitar el costo de cálculo adicional de decodificar números big-endian en máquinas little endian.
Si construye su protocolo sobre uno de estos protocolos existentes, entonces ni siquiera tiene que preocuparse por el problema usted mismo, ya está solucionado. Cuando decida ejecutar su código en una plataforma big-endian, las bibliotecas que implementan estos protocolos se encargarán automáticamente de garantizar que decodifique los valores correctamente.
fuente
Un ejemplo de un gran sistema endian es el MIPS utilizado en los enrutadores. Tanto ARM como MIPS son intercambiables por endian, pero a menudo MIPS es big endian porque facilita el hardware de la red (la parte más importante de una palabra es la parte que recibe primero y puede tomar una decisión de enrutamiento antes de que haya recibido el resto de la palabra, en lugar de tener que amortiguar toda la palabra).
Por lo tanto, depende de lo que quiera decir con 'Linux', pero si alguna vez desea ejecutar su aplicación de servidor en un sistema más pequeño como un enrutador que ejecuta OpenWRT, entonces puede que tenga que considerar el soporte de Big Endian.
Como de costumbre, hacer suposiciones simplificadoras es una optimización perfectamente sensata hasta el momento en que golpeas algo que no se ajusta a las suposiciones. Solo usted puede decir cuán doloroso sería relajarlos si alguna vez se encuentra con ese problema.
fuente
No creo que ninguna de las respuestas sea lo suficientemente precisa. Según Wikipedia, la endianidad es el orden de bytes que comprende una palabra.
Tomemos 4 bytes e interpretemos como int. En un pequeño sistema endian, los bytes se interpretarán de derecha a izquierda y viceversa en un sistema endian grande. Obviamente, es importante acordar en qué extremo interpretar un int.
Alejémonos un poco de los protocolos de red modernos que podrían estar usando json o xml. Ninguno de esos formatos transferirá un int como 4 bytes. Transferirán los datos como texto que se analizará como un int en el lado receptor.
Entonces, al final, la endianness no importa cuando se usa json o xml. Todavía necesitamos usar big endian para los encabezados tcp, por eso se llama orden de bytes de red, pero la mayoría de los programadores no necesitan meterse con ellos a diario.
La codificación más utilizada en la actualidad es la utf-8, que también es inmune a los problemas relacionados con la endianidad .
Entonces diría que sí. Es seguro ignorar la endianidad cuando se usan formatos basados en texto transferidos usando utf-8.
fuente
Los grandes sistemas endianos parecen estar saliendo. Muchos de los Unix tradicionales usaron Big Endian, pero han estado en declive durante años a favor de Linux en x86.
arm es bi-endian, pero la variante big endian parece raramente verse.
mips existe en ambas variantes. Adfaict, la variante big endian se ve principalmente en aplicaciones de red (por razones históricas, los protocolos de internet generalmente usan big endian).
ppc era tradicionalmente big endian con algunas partes compatibles con ambos endian, pero IBM parece ahora estar presionando el modo little endian para ppc de 64 bits (recientemente empujaron puertos ppc64el en Debian y Ubuntu).
sparc es normalmente big endian pero nuevamente parece estar en declive.
Si está implementando un protocolo existente, entonces obviamente debe seguir sus especificaciones. Si desea que el IETF bendiga su nuevo protocolo, es probable que big endian sea más fácil porque eso es lo que ya usan en sus protocolos existentes, pero la OMI para un nuevo diseño de protocolo "greenfield" little endian es el camino a seguir.
Puede poner macros desde el principio, que serán no operativos en pequeños sistemas endian o no puede molestarse hasta / a menos que necesite portar a un gran sistema endian.
fuente