Socket Unix - Órdenes de bytes de red

Desafortunadamente, no todas las computadoras almacenan los bytes que componen un valor multibyte en el mismo orden. Considere una Internet de 16 bits que se compone de 2 bytes. Hay dos formas de almacenar este valor.

  • Little Endian - En este esquema, el byte de orden inferior se almacena en la dirección inicial (A) y el byte de orden superior se almacena en la siguiente dirección (A + 1).

  • Big Endian - En este esquema, el byte de orden superior se almacena en la dirección inicial (A) y el byte de orden inferior se almacena en la siguiente dirección (A + 1).

Para permitir que las máquinas con diferentes convenciones de orden de bytes se comuniquen entre sí, los protocolos de Internet especifican una convención canónica de orden de bytes para los datos transmitidos a través de la red. Esto se conoce como orden de bytes de red.

Al establecer una conexión a Internet, debe asegurarse de que los datos de los miembros sin_port y sin_addr de la estructura sockaddr_in estén representados en el orden de bytes de la red.

Funciones de ordenación de bytes

Las rutinas para convertir datos entre la representación interna de un host y el orden de bytes de red son las siguientes:

Función Descripción
htons () Host a red corto
htonl () Host a red de largo
ntohl () Red para alojar durante mucho tiempo
ntohs () Red para acoger corto

A continuación se enumeran más detalles sobre estas funciones:

  • unsigned short htons(unsigned short hostshort) - Esta función convierte cantidades de 16 bits (2 bytes) del orden de bytes del host al orden de bytes de la red.

  • unsigned long htonl(unsigned long hostlong) - Esta función convierte cantidades de 32 bits (4 bytes) del orden de bytes del host al orden de bytes de la red.

  • unsigned short ntohs(unsigned short netshort) - Esta función convierte cantidades de 16 bits (2 bytes) del orden de bytes de la red al orden de bytes del host.

  • unsigned long ntohl(unsigned long netlong) - Esta función convierte cantidades de 32 bits del orden de bytes de la red al orden de bytes del host.

Estas funciones son macros y dan como resultado la inserción de código fuente de conversión en el programa de llamada. En las máquinas little-endian, el código cambiará los valores al orden de bytes de la red. En las máquinas big-endian, no se inserta ningún código ya que no es necesario; las funciones se definen como nulas.

Programa para determinar el orden de bytes del host

Mantenga el siguiente código en un archivo byteorder.cy luego compílelo y ejecútelo en su máquina.

En este ejemplo, almacenamos el valor de dos bytes 0x0102 en el entero corto y luego miramos los dos bytes consecutivos, c [0] (la dirección A) yc [1] (la dirección A + 1) para determinar el byte orden.

#include <stdio.h>

int main(int argc, char **argv) {

   union {
      short s;
      char c[sizeof(short)];
   }un;
	
   un.s = 0x0102;
   
   if (sizeof(short) == 2) {
      if (un.c[0] == 1 && un.c[1] == 2)
         printf("big-endian\n");
      
      else if (un.c[0] == 2 && un.c[1] == 1)
         printf("little-endian\n");
      
      else
         printf("unknown\n");
   }
   else {
      printf("sizeof(short) = %d\n", sizeof(short));
   }
	
   exit(0);
}

Una salida generada por este programa en una máquina Pentium es la siguiente:

$> gcc byteorder.c
$> ./a.out
little-endian
$>