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

我知道这里面大概有些东西..但是我的大脑伤害了,我找不到任何东西来做这个工作。

我试图通过一个unix套接字发送一个16位无符号整数..要做到这一点,我需要将uint16_t转换为两个字符,然后我需要在连接的另一端读取它们,并将其转换回任一无符号整数或uint16_t,在这一点上它没有关系,如果它使用2字节或4字节(我正在运行64位,这就是为什么我不能使用无符号整数:)

我正在用C做这个

谢谢

为什么不把它分成面具和轮班字节?

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

(编辑)

另一方面,你用相反的方式组装:

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

在我头顶,不知道是否需要这个演员。

 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 ); 

在一个小端机器上,这将把短端转换成大端,然后在远端从大端转换回来。 在一个大型机器上,这两个函数什么都不做。

当然,如果你知道网络中两台机器的架构使用相同的字节顺序,那么你可以避免这个步骤。

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

听起来就像你需要使用位掩码和移位操作符 。

将一个16位数字分成两个8位数字:

  • 使用按位AND运算符(&in C)掩盖低8位,使高8位全部变为0,然后将该结果分配给一个字符。
  • 使用右移运算符(>> C中的)将高8位右移,使得低8位全部被移出整数,只留下最高8位,并将其分配给另一个字符。

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

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

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

在另一端做相反的转换