2010-03-01 15 views
5

Siempre me han enseñado que si un número entero es más grande que un carácter, debe resolver el problema de orden de bytes. Por lo general, simplemente lo envuelvo en hton [l | s] y lo vuelvo a convertir con ntoh [l | s]. Pero estoy confundido por qué esto no se aplica a los caracteres de un solo byte.Conversión de orden de bytes de red con "char"

Estoy harto de preguntarme por qué es esto, y me encantaría que un experimentado programador de redes me ayude a arrojar algo de luz sobre por qué los pedidos de bytes solo se aplican a enteros multibyte.

Ref: http://beej.us/guide/bgnet/output/html/multipage/htonsman.html

+1

Apreciar las respuestas, tenían uno de esos "do'h "¡momentos! – Rev316

Respuesta

19

Lo que está buscando es endianness.

Un big endian arquitectura almacena los bytes de un tipo de datos de varios bytes de este modo:

big-endian

mientras que una arquitectura little-endian los almacena en reversa:

little-endian

Cuando los datos se transfieren de una máquina a otra, los bytes de un único tipo de datos se deben reordenar para que se correspondan con la endianidad de la máquina de destino.

Pero cuando un tipo de datos solo consta de un byte, , no hay nada que reordenar.

+0

+1, pero es posible que desee reconsiderar el robo del ancho de banda de otro sitio. – Bill

+1

@Bill, la política de Wikipedia sobre hotlinking está en http://commons.wikimedia.org/wiki/Commons:Reusing_content_outside_Wikimedia#Hotlinking - pero wikimedia.org está bloqueado aquí, así que no puedo leerlo yo mismo. ¿Te importaría parafrasearlo? ¡Gracias! –

+1

¡Aprendí algo nuevo hoy, gracias! Hotlinking parafraseado: "Ve a él, pero las imágenes pueden cambiar. Caveat scriptor". Bummer sobre el bloqueo. – Bill

4

Su pila de red se encargará de los bits dentro de los bytes correctamente, sólo debe preocuparse por conseguir los bytes en el orden correcto.

2

No lee bits individuales del cable, solo bytes. Independientemente de la endianidad, un solo byte es el mismo hacia atrás y hacia adelante al igual que la palabra "I" es la misma hacia atrás y hacia adelante.

+0

Muchos sistemas de ethernet codifican bits individuales; consulte http://en.wikipedia.org/wiki/MLT-3, aunque los más rápidos son mordiscos. –

4

Exactamente, ¿cuántas formas puedes pedir los bytes en un solo char?

+2

+1 por snark. Para deletrearlo: por definición, en C y C++ una char es la unidad de almacenamiento direccionable más pequeña. –

+3

-1 para snark.Usted sabe la respuesta a una pregunta que el OP no hizo. Bien por usted. No seas un idiota al respecto. –

+0

Aclare: el OP obviamente sabe acerca de ordenamiento de bytes y hton, etc. - por qué no necesita esto para un byte es solo uno de esos momentos. –

3

Debe tener en cuenta lo que hace cada función. A partir de eso, debe aplicar ese conocimiento al tamaño del tipo que pretende modificar. Considere lo siguiente:

#include <stdio.h> 
#include <netinet/in.h> 

int main() { 
    uint16_t i = 42; 
    uint8_t c = 42; // a char 
    printf ("(uint16_t) %08X (%d)\n", i, i); 
    printf ("( htons) %08X (%d)\n", htons(i), htons(i)); 
    printf ("(uint8_t) %08X (%c)\n", c, c); 
    printf ("( htons) %08X (%c)\n", htons(c), htons(c)); 
    return 0; 
} 

(uint16_t) 0000002A (42) 
( htons) 00002A00 (10752) 
(uint8_t) 0000002A (*) 
( htons) 00002A00() 
0

Además de todas las otras formas de la gente ha puesto que: Endianness es sobre el orden de bytes en un entero, no sobre el orden de los bits en un byte. El orden de los bits en un byte es el mismo incluso en las máquinas big-endian y little-endian. La única diferencia es el orden en el que los bytes se usan para almacenar un número entero (o abreviado o lo que tienes). Y así porque solo hay un byte en un char, no hay diferencia en cómo se almacena ese valor, ya sea en una arquitectura big-endian o little-endian.

+0

Incluso si realizo cómputos como bitwise o adds * (signed char) *? Esto es para convertir puntos de código Unicode contenidos en enteros en ᴜᴛꜰ-8. – user2284570

0

código EZPZ es incorrecta ..

uint16_t i = 65534; 
printf ("(uint16_t) %08X (%d)\n", i, i); 

Returns... 
(uint16_t) 0000FFFE (-2) 

Debe utilizar un entero sin signo en lugar así que no es interpretado como un int firmado

uint16_t i = 65534; 
printf ("(uint16_t) %08X (%u)\n", i, i); 

Returns... 
(uint16_t) 0000FFFE (65534) 
Cuestiones relacionadas