前言
在上一篇粘包的文章中提到,解决粘包的一种方式是,自定义消息,在消息头中增加包总长度的信息。不管tcp还是命名管道,都是以字节流的方式传递给接收者的。在解包的过程中,需要将头部的总长度信息提取出来,这就涉及到字节数字与int之间的转换。
另外,在不同的操作系统、处理器,数据的存储还有大小端之分:高位在前低位在后,低位在前高位在后。因此需要提供两种转换模式
具体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| // 大端:地址低位存储值的高位,地址高位存储值的低位 QByteArray BaseServer::intToByteArray(int len) { QByteArray byteArray; byteArray.resize(4); byteArray[3] = (unsigned char)(0x000000ff & len); byteArray[2] = (unsigned char)((0x0000ff00 & len) >> 8); byteArray[1] = (unsigned char)((0x00ff0000 & len) >> 16); byteArray[0] = (unsigned char)((0xff000000 & len) >> 24); return byteArray; }
int BaseServer::byteArrayToInt(QByteArray byteArray) { int len = byteArray[3] & 0x000000ff; len |= ((byteArray[2] << 8) & 0x0000ff00); len |= ((byteArray[1] << 16) & 0x00ff0000); len |= ((byteArray[0] << 24) & 0xff000000); return len; }
// 小端:地址低位存储值的低位,地址高位存储值的高位 QByteArray BaseServer::intToByteArray(int len) { QByteArray byteArray; byteArray.resize(4); byteArray[0] = (unsigned char)(0x000000ff & len); byteArray[1] = (unsigned char)((0x0000ff00 & len) >> 8); byteArray[2] = (unsigned char)((0x00ff0000 & len) >> 16); byteArray[3] = (unsigned char)((0xff000000 & len) >> 24); return byteArray; }
int BaseServer::byteArrayToInt(QByteArray byteArray) { int len = byteArray[0] & 0x000000ff; len |= ((byteArray[1] << 8) & 0x0000ff00); len |= ((byteArray[2] << 16) & 0x00ff0000); len |= ((byteArray[3] << 24) & 0xff000000); return len; }
|
其他补充
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian(大端)排序方式。因此,在大端CPU与网络序之间不需要考虑转换。