让我们看一下这段代码:
short bit = (payloadLength >> 0) & 1U; // get first bit
payloadLength &= 1UL << 0; // set first bit to 0
payloadLength = ntohl(payloadLength);
尽管您以这种方式订购这些陈述是完全合法的,但存在这样的风险,即这不会按照您想要的方式工作。具体来说,您可能希望在开始戳和刺激字节之前解码有效负载以使用主机字节顺序。否则,如果您将数据从一个系统发送到另一个系统,则存在读回错误位的风险。但这并不难解决 - 只需将最后一个解码的语句移到payloadLength顶部,如下所示:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = (payloadLength >> 0) & 1U; // get first bit
payloadLength &= 1UL << 0; // set first bit to 0
接下来,有一个关于您要阅读的位的问题。看起来您正在尝试读取数字的最低有效位。如果是这种情况,您不需要包含任何位移,因为位移零位没有任何效果。让我们删除那些,给出这个:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= 1UL; // set first bit to 0
您提取数字最后一位的代码是正确的。它会屏蔽除最低位以外的所有内容,然后将值存储在变量中bit。(出于好奇,您是否有任何理由将其存储short为bool
bool reencode = (payloadLength & 1U) != 0;
不过,这由您决定。)
但是,您清除最后一位的代码不正确。现在,当你写
payloadLength &= 1UL; // set first bit to 0
您实际上正在做与您的意图相反的事情-您正在清除除第一个以外的所有位。那是因为如果你payloadLength与一个值,你将归零payloadLength除了等于 1 in 的位之外的每一位1UL。但是,1UL最后一个位置只有 1 位。你可能打算写类似的东西
payloadLength &= ~1UL; // set first bit to 0
~ 运算符翻转掩码的位。总的来说,这将为您提供以下信息:
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= ~1UL; // set first bit to 0
不过,我还有最后一个问题。通过以这种方式重新利用数字的最低位,您要求有效载荷长度始终为偶数,因为您正在利用有效载荷长度的 1 位来编码是否重新加密。如果你没问题,那就太好了!你不需要做任何事情。
另一方面,如果这是一个问题,您有几个选项,我将留给您选择:
不要使用最低有效位,而是使用最高有效位。但是,如果您尝试发送大小为 2 31或更高的有效负载,这将导致问题。
使用最低有效位,但数字的高 31 位表示实际有效负载长度。要提取有效载荷长度,只需将所有内容移到一个位置即可。但是,这具有不支持大小为 2 31或更大的有效负载的缺点。
根本不要使用这些位来编码!相反,发送一个有效负载长度,然后让有效负载以一个标头开始,告诉您是否要重新设置密钥等。这将使用每个有效负载更多的字节,但也会在未来为您提供更多的灵活性(如果您需要发送其他标志为出色地?)
希望这可以帮助!