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

Mic*_*ook 11 c unix sockets tcp stream

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

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

我在C顺便说一下这样做

谢谢

Ste*_*dit 31

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

 uint16_t value = 12345;
 char lo = value & 0xFF;
 char hi = value >> 8;
Run Code Online (Sandbox Code Playgroud)

(编辑)

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

 uint16_t value = lo | uint16_t(hi) << 8;
Run Code Online (Sandbox Code Playgroud)

在我的头顶,不确定是否需要演员表.

  • and a year later it is still useful, so don't stop spreading good vibe (7认同)
  • 嗯,这个答案给我带来了很多痛苦,即使在你写完之后我用了一年多.谢谢. (4认同)
  • 抱歉所有,我忘记了所有关于这个问题...正在我的个人资料上做一些春季清洁并注意到这个并且去了oopsies :(给了这个正确的答案,因为从百万年前我做到了这一点,这确实响了我的铃声做到了......加上每个人似乎都喜欢这个答案.抱歉@StevenSudit (3认同)

Goz*_*Goz 5

char* pUint16 = (char*)&u16;
Run Code Online (Sandbox Code Playgroud)

即转换 uint16_t 的地址。

char c16[2];
uint16_t ui16 = 0xdead;
memcpy( c16, ui16, 2 );
Run Code Online (Sandbox Code Playgroud)

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

char* pC16 = /*blah*/
uint16_t ui16;
memcpy( &ui16, pC16, 2 );
Run Code Online (Sandbox Code Playgroud)

有趣的是,尽管有对 memcpy 的调用,但几乎每个编译器都会对其进行优化,因为它的大小是固定的。

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

uint16_t ui16correct = htons( 0xdead );
Run Code Online (Sandbox Code Playgroud)

在远端使用 ntohs(网络到主机短接)

uint16_t ui16correct = ntohs( ui16 );
Run Code Online (Sandbox Code Playgroud)

在小端机器上,这会将短端转换为大端,然后在远端从大端转换回来。在大端机器上,这两个函数什么也不做。

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

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