网络编程 - ByteArray

将一些基本数据类型(诸如string 、double、float、long)转化为网络字节序的思路有两种:

  1. 通过函数的方式进行字节颠倒,从而改变字节序
  2. 通过移位运算进行字节位置改变

函数转换

函数转换的思路比较直接,首先是判断当前设备是大端设备还是小端设备。如果是大端设备,那么在写入相应的字节数组时就不必调整。如果当前设备是小端设备,那么就通过相应的转换函数将字节序转换为大端序,然后再写入数组。

这种方式的核心是一个字节逆序函数,结构如下:

 /**
 * 将字节源 bytes 里的字节顺序反转
 * @param bytes 源字节
 * @param size 字节长度
 */
void ByteArray::reversalArray(char *bytes, size_t size)
{
    for(size_t i = 0; i < size / 2; i++){
        char temp;
        temp = *(bytes + i);
        *(bytes + i) = *(bytes + size - i - 1);
        *(bytes + size - i - 1) = temp;
    }
}

完整示例:https://github.com/sbxfc/ReversalByteArray

移位运算

另外一种改变字节顺序的方式是移位运算。由于移位运算是在寄存器中进行的运算,所以使用移位运算符在对一个数值进行移位操作时不需要考虑内存的排列顺序,永远左侧是高位右侧是低位。

获取一个高位字节时,首先移除相应的低位字节,然后通过&运算符与0xff运算获取一个高位字节的数据:

//右移8位,相当于去掉了低位上的8个字节
bytesBuf[writePos++] = (value >> 8) & 0xff;

在将字节转化为数值时,首先通过移位运算,设置相应高位或低位值,然后利用|运算符将不同位合并:

short value = 0;
value  = (bytes[0] & 0xff) << 8;
value |= (bytes[1] & 0xff);

完整代码:https://github.com/sbxfc/ByteArray

运算符 &

与运算符&两侧的数据,按照二进制数据进行与运算,比如两侧数据的二进制值分别是 0011 和0101,当进行&运算时:

0&0=0;
0&1=0;
1&0=0;
1&1=1;

只有两位同时为1,结果才为1,否则为0。在大小端转化时,进行按位与运算,相当于对数值进行byte类型强转。

运算符 |

按位“或”的运算规则和按位“与”相反

0&0=1;
0&1=1;
1&0=1;
1&1=0;

Comments