常州網(wǎng)站優(yōu)化營銷軟文小短文
1.大小端數(shù)據(jù)簡介
大小端(Endianness)是計(jì)算機(jī)體系結(jié)構(gòu)的一個(gè)術(shù)語,它描述了多字節(jié)數(shù)據(jù)在內(nèi)存中的存儲順序。以下是大小端的定義和它們的特點(diǎn):
大端(Big-Endian)
在大端模式中,一個(gè)字的最高有效字節(jié)(MSB,即最左邊的那位)存儲在最低的內(nèi)存地址處,而最低有效字節(jié)(LSB,即最右邊的那位)存儲在最高的內(nèi)存地址處。
例如,假設(shè)有一個(gè)16位的數(shù)字 0x1234,其在內(nèi)存中的存儲順序如下:
地址增加方向 -->
[ 12 ] [ 34 ]
其中 [12] 是高字節(jié),存儲在低地址處;[34] 是低字節(jié),存儲在高地址處。
小端(Little-Endian)
在小端模式中,情況正好相反:一個(gè)字的最低有效字節(jié)存儲在最低的內(nèi)存地址處,而最高有效字節(jié)存儲在最高的內(nèi)存地址處。
繼續(xù)上面的例子,16位的數(shù)字 0x1234 在小端模式下的存儲順序如下:
地址增加方向 -->
[ 34 ] [ 12 ]
其中 [34] 是低字節(jié),存儲在低地址處;[12] 是高字節(jié),存儲在高地址處。
2.小端數(shù)據(jù)收發(fā)
假設(shè)我們現(xiàn)在有一個(gè)UDP頭的數(shù)據(jù)結(jié)構(gòu)如下所示。
//UDP協(xié)議頭typedef struct{quint16 type; //報(bào)文類型quint16 num; //報(bào)文序號,取值范圍為0~65535quint32 len; //報(bào)文長度quint16 srcAddr; //信源地址quint16 dstAddr; //信宿地址quint8 year; //發(fā)送時(shí)間 年份后兩位 UTC時(shí)間quint8 month;quint8 day;quint8 hour;quint8 minute;quint8 second;}UdpHeader;
數(shù)據(jù)發(fā)送:組包。
QByteArray pack(const Protocol::UdpHeader &header)
{QByteArray byte;byte.append((char*)&(header.type),2);byte.append((char*)&(header.num),2);byte.append((char*)&(header.len),4);byte.append((char*)&(header.srcAddr),2);byte.append((char*)&(header.dstAddr),2);QString format = "yy-MM-dd-hh-mm-ss";QDateTime dateTime = QDateTime::currentDateTime();dateTime.setTimeSpec(Qt::LocalTime);QDateTime utcTime = dateTime.toUTC();QString strUtcTime = utcTime.toString(format);QStringList timeList = strUtcTime.split('-');quint8 year = timeList.at(0).toInt();quint8 month = timeList.at(1).toInt();quint8 day = timeList.at(2).toInt();quint8 hour = timeList.at(3).toInt();quint8 minute = timeList.at(4).toInt();quint8 sec = timeList.at(5).toInt();byte.append(year);byte.append(month);byte.append(day);byte.append(hour);byte.append(minute);byte.append(sec);return byte;
}
數(shù)據(jù)接收:拆包
void unPack(const QByteArray &byte, Protocol::UdpHeader &header)
{if(byte.size() != UDP_HEADER_LEN){return;}memcpy(&header,byte.data(),sizeof(Protocol::UdpHeader));
}
3.大端數(shù)據(jù)收發(fā)
還是上面的頭例子。
數(shù)據(jù)發(fā)送:組包。
使用QDataStream類作為輔助,設(shè)置setByteOrder為大端序列。
QByteArray packBigEndian(const Protocol::UdpHeader &header)
{QByteArray byte;QDataStream stream(&byte,QIODevice::WriteOnly);stream.setByteOrder(QDataStream::BigEndian);stream<<(header.type);stream<<(header.num);stream<<(header.len);stream<<(header.srcAddr);stream<<(header.dstAddr);QString format = "yy-MM-dd-hh-mm-ss";QDateTime dateTime = QDateTime::currentDateTime();dateTime.setTimeSpec(Qt::LocalTime);QDateTime utcTime = dateTime.toUTC();QString strUtcTime = utcTime.toString(format);QStringList timeList = strUtcTime.split('-');quint8 year = timeList.at(0).toInt();quint8 month = timeList.at(1).toInt();quint8 day = timeList.at(2).toInt();quint8 hour = timeList.at(3).toInt();quint8 minute = timeList.at(4).toInt();quint8 sec = timeList.at(5).toInt();stream<<year;stream<<month;stream<<day;stream<<hour;stream<<minute;stream<<sec;return byte;
}
數(shù)據(jù)接收:拆包。
對于多字節(jié)的數(shù)據(jù),都需要單獨(dú)使用qToBigEndian轉(zhuǎn)換為大端。
void unPackBigEndian(const QByteArray &byte, Protocol::UdpHeader &header)
{if(byte.size() != UDP_HEADER_LEN){return;}memcpy(&header,byte.data(),sizeof(Protocol::UdpHeader));header.type = qToBigEndian(header.type);header.num= qToBigEndian(header.num);header.len= qToBigEndian(header.len);header.srcAddr= qToBigEndian(header.srcAddr);header.dstAddr= qToBigEndian(header.dstAddr);
}