【问题标题】:Changing certain byte in a packet stream更改数据包流中的某些字节
【发布时间】:2010-09-23 19:36:47
【问题描述】:

我正在使用 C 来实现将通过无线发送的数据包流,但遇到以下问题。我有一个 2 字节长的无符号整数,二进制格式如下: XXXX YYYY XXXX XXXX,其中 X 和 Y 是位。

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

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

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

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

谢谢!

【问题讨论】:

    标签: c


    【解决方案1】:

    假设您想用 ZZZZ 替换 YYYY 位。

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

    oldvalue & 0xF0FF
    

    给你XXXX 0000 XXXX XXXX。

    接下来,您需要获取新的 ZZZZ 位并将它们向左移动:

    z << 8
    

    给出0000 ZZZZ 0000 0000。

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

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

    给你XXXX ZZZZ XXXX XXXX。

    【讨论】:

    • 感谢您的解释!效果很好
    【解决方案2】:

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

    【讨论】:

    • 太棒了!谢谢你。发布此问题后,我再次尝试并提出了相同的逻辑,但您的代码更简单且切中要害(我有 4 行可以在一行中完成)
    • 没问题,skybox - 很高兴为您提供帮助!
    【解决方案3】:

    您对问题的描述可以使用一些代码,但我认为您可能遇到了字节序问题。这可以解释为什么您的移位和屏蔽没有按照您的想法执行,因为您实际上是在处理错误的字节。

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

    这个函数不会改变传入数据相对于返回值的字节序,但它确实假设该值是网络字节序,因此将掩码的字节序从主机字节序更改为网络字节序,然后在结果中设置这些位。

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

    【讨论】:

    • 谢谢!小/大端的经验教训。数字世界的新手。将更多地研究您的代码并尝试弄清楚。
    猜你喜欢
    • 2020-10-17
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 2015-06-13
    相关资源
    最近更新 更多