更改数据包流中的某个字节

时间:2010-09-23 19:36:48

标签: c

我正在使用C来实现将通过无线发送的数据包流,并且遇到以下问题。我有一个2字节长的unsigned int,在二进制文件中采用以下格式: XXXX YYYY XXXX XXXX,其中X& Y是比特。

查看上面的格式,我需要更改YYYY位并将其他位保留在数据包结构中。

我尝试过移位和屏蔽,但似乎没有任何效果。

我不是在寻找一个解决方案,所以我可以复制/粘贴。我想学习如何让它工作的方法,最后决定在这里发布。

任何正确方向的帮助或指导都会很棒。

谢谢!

3 个答案:

答案 0 :(得分:6)

假设您想用ZZZZ替换YYYY位。

首先,您需要清除原始值中的YYYY位。这可以通过以下方式完成:

oldvalue & 0xF0FF

为您提供XXXX 0000 XXXX XXXX

接下来,您需要使用新的ZZZZ位并将它们移到左侧,使用:

z << 8

给出了0000 ZZZZ 0000 0000

最后,您需要使用或运算符组合这两个值:

(oldvalue & 0xF0FF) | (z << 8)

为您提供XXXX ZZZZ XXXX XXXX

答案 1 :(得分:0)

value = (value & 0xF0FF) | (newY << 8);或其近似变体,取决于字节顺序?

答案 2 :(得分:0)

您对问题的描述可能与某些代码有关,但我认为您可能遇到了一个字节序问题。这可以解释为什么你的移位和掩蔽没有按照你的想法去做,因为你实际上在处理错误的字节。

hton和ntoh函数系列切换到主机和网络端(大端)。查看htons,ntohs,htonl和ntohl以获取更多信息。如果主机是大端,这些功能实际上并没有做任何事情,但许多(如x86)计算机都是小端。在一个小端计算机上,htons(0x1234)会导致0x3412,因为它会交换字节。

因为我不知道你的程序流程是什么样的,所以我最好尝试一个明确的例子。

uint16_t set_those_bits(uint16_t x) {
    uint16_t mask = htons(0x0F00);
    return x | mask;
}

此函数不会改变相对于返回值传入的数据的字节序,但它确实假定该值为network endian,因此将掩码的endian-ness从host endian更改为network在结果中设置这些位。

uint16_t clear_those_bits(uint16_t x) {
    uint16_t mask = htons(0xF0FF);
    return x & mask;
}

uint16_t toggle_those_bits(uint16_t x) {
    uint16_t mask = htons(0x0f00);
    return x ^ mask;
}
相关问题