2011-02-02 22 views
7

Me gustaría convertir un int32_t del orden de bytes del host al orden de bytes de la red y viceversa. Sé acerca de la función htonl() y sus variantes, pero esto toma enteros sin signo. ¿Hay una función de biblioteca estándar que pueda hacer lo mismo con los enteros con signo o tengo que implementarlo yo mismo? Y si tengo que implementarlo yo mismo, ¿cómo debería hacerlo?Conversión de red y host con número entero firmado

estoy en busca de encontrar una rutina que funcione en Linux y Mac OS X.

+0

¿Qué significa eso - ¿Qué esperas que ver con el bit firmada de que no sucedería en que acaba de utilizar la función sin firmar y ¿moldes? – Rup

Respuesta

8

No importa. htonl se ocupa de los bytes, no del valor aritmético del número. Use reinterpret_cast para cambiar el número a unsigned y viceversa, si es necesario.

+11

Dado que está utilizando C, probablemente debería simplemente llamar a 'htonl ((uint32_t) address);' – joeforker

+0

@ joeforker que conducirá a un comportamiento indefinido en caso de desbordamiento. por favor borre su comentario. use 'memcpy' en su lugar. – rightfold

+0

Funciona, solo intercambia cuatro bytes. Sin desbordamiento OTOH memcpy() deja los bytes en el mismo orden. – joeforker

2

Si un sistema (nunca se sabe lo que podría estar ejecutando Linux) puede usar representaciones diferentes para enteros negativos (por ejemplo, el complemento, magnitud de signo, raro, pero posible), transmite los números como cadenas y analízalos en Ints en el receptor. No es tan eficiente, pero a menos que esté transmitiendo una gran cantidad de números, no importará mucho. Si hay muchos números para transmitir, puede usar alguna forma de compresión.

O bien, defina su propia representación de red para números negativos y escriba su propia ntohsl y htonsl.

En cualquier enfoque, habrá un número en cada sistema que no se puede representar en el otro; tendrá que decidir cuál es el curso de acción apropiado al recibir este número.

0

Si está utilizando gcc tiene un conjunto de builtins para este propósito. Usualmente se compilan en una sola instrucción.

uint16_t __builtin_bswap16 (uint16_t x); 
uint32_t __builtin_bswap32 (uint32_t x); 
uint64_t __builtin_bswap64 (uint64_t x); 

En mi máquina, __builtin_bswap32() compilado para

bswap %eax