Frage

I have been wanting to experiment with this project Axon with an iOS app connecting over a tcp connection. Towards the end of the doc the protocol is explained as so

The wire protocol is simple and very much zeromq-like, where is a BE 24 bit unsigned integer representing a maximum length of roughly ~16mb. The data byte is currently only used to store the codec, for example "json" is simply 1, in turn JSON messages received on the client end will then be automatically decoded for you by selecting this same codec.

With the diagram

 octet:     0      1      2      3      <length>
         +------+------+------+------+------------------...
         | meta | <length>           | data ...
         +------+------+------+------+------------------...

I have had experience working with binary protocols creating a packet such as:

NSUInteger INT_32_LENGTH = sizeof(uint32_t);

uint32_t length = [data length]; // data is an NSData object

NSMutableData *packetData = [NSMutableData dataWithCapacity:length + (INT_32_LENGTH * 2)];
[packetData appendBytes:&requestType length:INT_32_LENGTH]; 
[packetData appendBytes:&length length:INT_32_LENGTH];                  
[packetData appendData:data];                                           

So my question is how would you create the data packet for the Axon request, I would assume some bit shifting, which I am not too clued up on.

War es hilfreich?

Lösung

Allocate 1 array of char or unsigned char with size == packet_size; Decalre constants:

const int metaFieldPos = 0;
const int sizeofMetaField = sizeof(char);
const int lengthPos = metaFieldPos + sizeofMetaField;
const int sizeofLengthField = sizeof(char) * 3;
const int dataPos = lengthPos + sizeofLengthField;

If you got the data and can recognize begining of the packet, you can use constants above to navigate by pointers.

May be these functions will help you (They use Qt, but you can easily translate them to library, that you use)

quint32 Convert::uint32_to_uint24(const quint32 value){
    return value & (quint32)(0x00FFFFFFu);
}

qint32 Convert::int32_to_uint24(const qint32 value){
    return value & (qint32)(0x00FFFFFF);
}

quint32 Convert::bytes_to_uint24(const char* from){
    quint32 result = 0;
    quint8 shift = 0;
    for (int i = 0; i < bytesIn24Bits; i++) {
        result |= static_cast<quint32>(*reinterpret_cast<const quint8 *>(from + i)) << shift;
        shift+=bitsInByte;
    }
    return result;
}

void Convert::uint32_to_uint24Bytes(const quint32 value, char* from){
    quint8 shift = 0;
    for (int i = 0; i < bytesIn24Bits; i++) {
        const quint32 buf = (value >> shift) & 0xFFu;
        *(from + i) = *reinterpret_cast<const char *>(&buf);
        shift+=bitsInByte;
    }
}

QByteArray Convert::uint32_to_uint24QByteArray (const quint32 value){
    QByteArray bytes;
    bytes.resize(sizeof(value));
    *reinterpret_cast<quint32 *>(bytes.data()) = value;
    bytes.chop(1);
    return bytes;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top