How to encode/decode and write and read binary data?
-
Hello!
I'm writing a server and part of the messages I receive are headers. The Header is constructed in the following way:
-
First byte: binary operation code (Size 1 Byte)
-
Bytes 1-3: Header Checksum:(Size 2 Bytes)
-
Bytes 4-8 Payload index (Size 4 Bytes)
-
Bytes 9 - 10 Payload Checksum (Size 2 Bytes)
Altogether 9 Bytes.
I want to use binary encoding for things such as the operation code and the payload index rather than ASCII encoding because 1-byte ASCII encoding would give me at most
0-9
(10 options), while one byte in binary will give me00000000 - 11111111
(256 options)However, I'm unsure how to parse this information on the receiving end. I've looked at
QBuffer
andQDataStream
which seems to be most suitable for the task. But couldn't figure out exactly how to perform the task I need.For example, when I get a new message from a client that is stored in a QTcpesocket's buffer, I read the first 9 bytes.
QByteArray ba; ba.append(this->socket->read(this->HEADER_SIZE)) ; //HEADER_SIZE = 9
So now I have my whole header in the
ba
ByteArray. Now I want to separate it into chunks and parse them individually. I thought of doing something like this:QBuffer buffer(&receivedHeaderByteArray); buffer.open(QIODevice::ReadOnly); QByteArray opCodeByteArray = buffer.read(1); QByteArray headerCheckSumByteArray = buffer.read(2); QByteArray payloadIndex = buffer.read(4) ; QByteArray payloadChecksum = buffer.read(2);
Presumably, now I have my header info separated into chunks but how do I convert the bytes in
opCodeByteArray
from a binary representation into an int?Would something like this be correct:
QByteArray opCodeByteArray = buffer.read(1); QBuffer buffer(&opCodeByteArray ); buffer.open(QIODevice::ReadOnly); qint8 opCodeInt; in >> opCodeInt;
Also, How would I encode an int into a binary value? For example, if I want to write '7'it would be '111' in binary. But sending '111' in ASCII would take 3 Bytes while encoded to binary it will be only one byte '00000111'
-
-
Hello!
I'm writing a server and part of the messages I receive are headers. The Header is constructed in the following way:
-
First byte: binary operation code (Size 1 Byte)
-
Bytes 1-3: Header Checksum:(Size 2 Bytes)
-
Bytes 4-8 Payload index (Size 4 Bytes)
-
Bytes 9 - 10 Payload Checksum (Size 2 Bytes)
Altogether 9 Bytes.
I want to use binary encoding for things such as the operation code and the payload index rather than ASCII encoding because 1-byte ASCII encoding would give me at most
0-9
(10 options), while one byte in binary will give me00000000 - 11111111
(256 options)However, I'm unsure how to parse this information on the receiving end. I've looked at
QBuffer
andQDataStream
which seems to be most suitable for the task. But couldn't figure out exactly how to perform the task I need.For example, when I get a new message from a client that is stored in a QTcpesocket's buffer, I read the first 9 bytes.
QByteArray ba; ba.append(this->socket->read(this->HEADER_SIZE)) ; //HEADER_SIZE = 9
So now I have my whole header in the
ba
ByteArray. Now I want to separate it into chunks and parse them individually. I thought of doing something like this:QBuffer buffer(&receivedHeaderByteArray); buffer.open(QIODevice::ReadOnly); QByteArray opCodeByteArray = buffer.read(1); QByteArray headerCheckSumByteArray = buffer.read(2); QByteArray payloadIndex = buffer.read(4) ; QByteArray payloadChecksum = buffer.read(2);
Presumably, now I have my header info separated into chunks but how do I convert the bytes in
opCodeByteArray
from a binary representation into an int?Would something like this be correct:
QByteArray opCodeByteArray = buffer.read(1); QBuffer buffer(&opCodeByteArray ); buffer.open(QIODevice::ReadOnly); qint8 opCodeInt; in >> opCodeInt;
Also, How would I encode an int into a binary value? For example, if I want to write '7'it would be '111' in binary. But sending '111' in ASCII would take 3 Bytes while encoded to binary it will be only one byte '00000111'
Edit
Bytes 1-3 [...] Size 2 Bytes
does not hold mathematically but nevermind
@Curtwagner1984 said in How to encode/decode and write and read binary data?:
Now I want to separate it into chunks and parse them individually
First byte:
ba.front()
;
Bytes 1-3:ba.mid(1,2);
Bytes 4-8:ba.mid(4,4);
Bytes 9 - 10:ba.mid(9,2);
How would I encode an int into a binary value? For example, if I want to write '7'
QDataStream baStream(&ba,QIODevice::WriteOnly); baStream << static_cast<quint8>(7);
-
-
Edit
Bytes 1-3 [...] Size 2 Bytes
does not hold mathematically but nevermind
@Curtwagner1984 said in How to encode/decode and write and read binary data?:
Now I want to separate it into chunks and parse them individually
First byte:
ba.front()
;
Bytes 1-3:ba.mid(1,2);
Bytes 4-8:ba.mid(4,4);
Bytes 9 - 10:ba.mid(9,2);
How would I encode an int into a binary value? For example, if I want to write '7'
QDataStream baStream(&ba,QIODevice::WriteOnly); baStream << static_cast<quint8>(7);
@VRonin said in How to encode/decode and write and read binary data?:
First byte:
ba.front()
;
Bytes 1-3:ba.mid(1,2);
Bytes 4-8:ba.mid(4,4);
Bytes 9 - 10:ba.mid(9,2);
Thanks! What did you mean 'does not hold mathematically?'
And converting this to ints would be done like this:?QByteArray opCode = ba.front(); QDataStream baStream(&opCode,QIODevice::ReadOnly); qint8 opCodeInt; baStream >> opCodeInt;
-
@VRonin said in How to encode/decode and write and read binary data?:
First byte:
ba.front()
;
Bytes 1-3:ba.mid(1,2);
Bytes 4-8:ba.mid(4,4);
Bytes 9 - 10:ba.mid(9,2);
Thanks! What did you mean 'does not hold mathematically?'
And converting this to ints would be done like this:?QByteArray opCode = ba.front(); QDataStream baStream(&opCode,QIODevice::ReadOnly); qint8 opCodeInt; baStream >> opCodeInt;
@Curtwagner1984 said in How to encode/decode and write and read binary data?:
What did you mean 'does not hold mathematically?'
Bytes 1-3 is 3 Bytes (1,2 and 3), not 2
And converting this to ints
please be very careful with terminology here. Qt requires
int
to be 4 bytes in size, with that comes the problem of endianness.
If you just mean the numeric value in each byte you can just iterate over the internal buffer using.cbegin()
/cend()
or by usingba.data()[i]
-
@Curtwagner1984 said in How to encode/decode and write and read binary data?:
What did you mean 'does not hold mathematically?'
Bytes 1-3 is 3 Bytes (1,2 and 3), not 2
And converting this to ints
please be very careful with terminology here. Qt requires
int
to be 4 bytes in size, with that comes the problem of endianness.
If you just mean the numeric value in each byte you can just iterate over the internal buffer using.cbegin()
/cend()
or by usingba.data()[i]
@VRonin said in How to encode/decode and write and read binary data?:
@Curtwagner1984 said in How to encode/decode and write and read binary data?:
What did you mean 'does not hold mathematically?'
Bytes 1-3 is 3 Bytes (1,2 and 3), not 2
Oh, my bad...
I thought you meant the whole concept doesn't hold mathematically...And converting this to ints
please be very careful with terminology here. Qt requires
int
to be 4 bytes in size, with that comes the problem of endianness.Could you please elaborate on this? Isn't this what qint8 and qint16 are for?
-
Take the "Header Checksum" for example they are already stored as qint8 numerals inside
QByteArray
, if you want to convert those 2 bytes in a 4 bytesint
then it becomes a problem. If you just want to access the values you can useconstData().operator[]
const QByteArray checksum= ba.mid(1,2); qDebug() << "First Byte in decimal" << static_cast<qint16>(checksum.constData()[0]); //the cast is necessary otherwise qDebug() will try to print an ascii value qDebug() << "Full Values in hexadecimal" << checksum.toHex();