我正在查看此Java代码并试图理解它。我了解所有有关它的内容,除了移位部分。
我知道下面使用位移的代码正在建立一些值以填充byte [],但我不知道为什么专门使用右移,为什么要先使用24位,然后是16位,然后再选择8位?这些值在何处以及为什么被选择,而不是其他一些值?
private void Send(NetSocket out, int MsgID, byte MsgSeq, char MsgLetter, String data)
{
int msglen = data.length() + 2;
byte[] msg = new byte[msglen + 8];
byte[] md = data.getBytes();
msg[0] = (byte) (msglen >> 24);
msg[1] = (byte) (msglen >> 16);
msg[2] = (byte) (msglen >> 8);
msg[3] = (byte) (msglen);
msg[4] = (byte) (MsgID >> 24);
msg[5] = (byte) (MsgID >> 16);
msg[6] = (byte) (MsgID >> 8);
msg[7] = (byte) (MsgID);
msg[8] = (byte) MsgLetter;
msg[9] = MsgSeq;
System.arraycopy(md, 0, msg, 10, msglen - 2);
// send
}
答案 0 :(得分:1)
这只是将32位整数的4个字节打包为4个连续的字节,请注意使用特定的字节序(在这种情况下为big-endian)。只是说:
// put the "biggest" 8 bits into the first byte,
// by right shifting the value 24 bits
msg[0] = (byte) (msglen >> 24);
将32位整数右移24位意味着您在最低有效8位中剩下8个最高有效位,可以打包到byte
中。接下来的3行处理接下来的8位(右移16),然后处理下一个(右移8),依此类推。
仅向byte
投射丢弃除最低有效8位以外的所有内容,因此,在每次移位后(或最后一个移位中都没有移位),我们取四分之一32位。
再说一遍:这只是实现了帧的大端长度前缀。接收代码将通过左移和或将其反转,以从前4个字节重建长度。
答案 1 :(得分:1)
如果您有32位整数,可以将其视为四个8位整数:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
bits 24-31 (8 bits) bits 16-23 (8 bits) bits 8-15 (8 bits) bits 0-7 (8 bits)
Big-endian 编码是您首先发送最高有效字节的位置,因此,您需要第一个字节中的24-31位,第二个字节中的16-23位,依此类推。网络通信的标准字节顺序为big-endian。 ( Little-endian 是另一种方法,通常用于x86和某些其他平台上的内存中存储。)
如果将整数转换为字节,则会丢弃最高有效位位。
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
bits 24-31 (8 bits) bits 16-23 (8 bits) bits 8-15 (8 bits) bits 0-7 (8 bits)
cast to (byte)
07 06 05 04 03 02 01
\------------------/
bits 0-7 (8 bits)
如果您右移,则将这些位移开,以便可以转换为(byte)
并依次获取32位整数的其他部分:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
\---------------------/ \---------------------/ \---------------------/ \------------------/
bits 24-31 (8 bits) bits 16-23 (8 bits) bits 8-15 (8 bits) bits 0-7 (8 bits)
|
\---------------------------- >> 24 -----------------------------------\
|
07 06 05 04 03 02 01
\------------------/
previously bits 24-31
now bits 0-7 (8 bits)