从位流读取uint16_t

reading uint16_t from bit stream

本文关键字:uint16 读取      更新时间:2023-10-16

我正在尝试从u_char流指针(恰好指向 ip 标头)读取uint16_t,但很难获得合理的结果。

现在当我运行时:

uint16_t len16 = *stream;

或者当我运行以下内容时,以防网络和主机字节顺序之间存在差异:

uint16_t len16 = *stream;
len16 = ntohs(len16);

我在uint16_t没有得到预期的结果。但是当我运行时:

uint8_t total_len1, total_len2;
uint16_t total_len;
//get length1
total_len1 = *stream;
//advance pointer
stream += sizeof(uint8_t);
//get length2
total_len2 = *stream;
//advance pointer
stream += sizeof(uint8_t);

以total_len1和十六进制格式获得我期望的结果total_len2。那么这里发生了什么,我如何将这个值直接读取到uint16_t中?

读取

*stream将获得stream的一个元素的值(u_charuint8_t)。您想从stream 中读取uint16_t。在这种情况下,您将不得不重新转换其类型以将其读取为uint16_t数组。

uint16_t len16 = *(uint16_t *)stream;
len16 = ntohs(len16);

内存中发生了什么:

stream指向以下字节序列:

| byte 1  | byte 2  | byte 3  | byte 4  | byte 5  | byte 6  | ...
| uint8_t | uint8_t | uint8_t | uint8_t | uint8_t | uint8_t | ...

stream是一个uint8_t数组,因此通过读取stream元素,您一次读取一个字节。

现在stream类型重新转换为uint16_t数组,您可以成对读取字节,形成 16 位值:

| byte 1  | byte 2  | byte 3  | byte 4  | byte 5  | byte 6  | ...
|     uint16_t      |     uint16_t      |     uint16_t      | ...

使用u_char时要小心,这种类型不是C++标准,其大小可能因编译器而异。