将uint16_t转换为char [2]以通过套接字(unix)发送

时间:2012-11-07 22:00:47

标签: c sockets unix tcp stream

我知道那里有大致的东西......但我的大脑受伤了,我找不到任何东西让这项工作......

我试图在unix套接字上发送一个16位无符号整数。为此,我需要将uint16_t转换为两个字符,然后我需要在连接的另一端读取它们并将其转换回来无论是unsigned int还是uint16_t,此时无论是使用2bytes还是4bytes都没关系(我运行的是64bit,这就是为什么我不能使用unsigned int :)。

我在C btw

中这样做

谢谢

4 个答案:

答案 0 :(得分:30)

为什么不用掩码和移位将其分解为字节?

 uint16_t value = 12345;
 char lo = value & 0xFF;
 char hi = value >> 8;

(编辑)

另一方面,你反过来组装:

 uint16_t value = lo | uint16_t(hi) << 8;

离开我的头顶,不确定是否需要演员。

答案 1 :(得分:3)

char* pUint16 = (char*)&u16;

即转换uint16_t的地址。

char c16[2];
uint16_t ui16 = 0xdead;
memcpy( c16, ui16, 2 );

c16现在包含u16的2个字节。在远端,您可以简单地颠倒过程。

char* pC16 = /*blah*/
uint16_t ui16;
memcpy( &ui16, pC16, 2 );

有趣的是,虽然对memcpy的调用几乎每个编译器都会优化它,因为它具有固定的大小。

正如Steven sudt所指出的,你可能会遇到大端问题。为了解决这个问题,您可以使用htons(主机到网络短路)功能。

uint16_t ui16correct = htons( 0xdead );

并且在远端使用ntohs(网络到主机短路)

uint16_t ui16correct = ntohs( ui16 );

在一个小端机器上,这会将短路转换为大端,然后在远端将大端转换回来。在大端机器上,2个功能什么都不做。

当然,如果您知道网络上两台计算机的体系结构使用相同的字节序,那么您可以避免这一步骤。

查找ntohl和htonl以处理32位整数。大多数平台也支持64位的ntohll和htonll。

答案 2 :(得分:2)

听起来你需要使用bit mask and shift operators

将16位数字拆分为两个8位数字:

  • 使用按位AND运算符(&amp; in C)屏蔽低8位,以便高8位全部变为0,然后将结果分配给一个字符。
  • 使用右移位运算符(&gt;&gt;在C中)将高8位向右移位,以便将低8位全部推出整数,只留下前8位,并将其分配给另一个字符。

然后,当你通过连接发送这两个字符时,你会反过来:你将以前的8位向左移动8位,然后使用按位OR将其与其他8位组合。

答案 3 :(得分:1)

基本上你是通过套接字发送2个字节,这是所有套接字需要知道的,无论字节顺序,签名等等......只需将你的uint16分解为2个字节并通过套接字发送它们。

char byte0 = u16 & 0xFF;
char byte1 = u16 >> 8;

另一端以相反的方式进行转换