Пытаюсь сделать AMF3 Packet

Я пытаюсь сделать AMF Packet. я использую https://github.com/Ventero/amf-cpp Реализация AMF3 на C ++, но она не содержит всех необходимых переменных.
Документация AMF0 описывает, как построен пакет AMF (http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf)
Первые два байта указывают версию пакета:

версия = U16
Это может быть 0 или 3

U16 — 16-разрядное целое число без знака в старшем порядке
(сетевой) порядок байтов

Итак, я создал

typedef unsigned int u16;

В amf.hpp
Я пытаюсь сейчас добавить всю информацию заголовка в одну переменную std :: vector.
Я написал:

std::vector<u16> buf = std::vector<u16>{3};  //packet version
std::vector<u16> buf2 = std::vector<u16>{0}; //header-count
std::vector<u16> buf3 = std::vector<u16>{1}; //message count

std::vector<u16> data;

buffermain.insert(data.end(), buf.begin(), buf.end());
buffermain.insert(data.end(), buf2.begin(), buf2.end());
buffermain.insert(data.end(), buf3.begin(), buf3.end());

В результате в данных я просто вставил вектор (buf).

//редактировать
Я добился определенного прогресса.

Serializer serializer;
QByteArray outArray; //to insert amf bytes, and send it later

AmfArray Content;
AmfObject Object;

Object.addSealedProperty("Source", AmfNull());
Object.addSealedProperty("operation", AmfNull());
Object.addSealedProperty("clientId", AmfNull());
Object.addSealedProperty("destination", AmfNull());
Object.addSealedProperty("messageId", AmfNull());
Object.addSealedProperty("timestamp", AmfNull());
Object.addSealedProperty("timeToLive", AmfNull());
Object.addSealedProperty("timeToLive", AmfNull());
Object.addSealedProperty("body", AmfNull());
Object.addSealedProperty("headers", AmfNull());

Content.push_back(Object);
serializer << Content;

std::vector<uint8_t> data2 = serializer.data();

char* datas = reinterpret_cast<char*>(data2.data());//

std::vector<unsigned __int32> v;
v.reserve(data.size());

char* sizes = reinterpret_cast<char*>(v.data()); //teoretical size of message in U32

char null = 0;
outArray.append(null); //version first byte
outArray.append(3); //version second byte
outArray.append(null); //header count first byte
outArray.append(null); //header count second byte
outArray.append(null); //messages count first byte
outArray.append(1); //messages count second byte

outArray.append(null); //"Target" lenght first byte
outArray.append(4); //"Target" lenght second byte

outArray.append(QByteArray::fromHex("6e756c6c")); // "Target" value

outArray.append(null); // "Response" length first byte
outArray.append(2); // "Response" length second byte

outArray.append(QByteArray::fromHex("2f31"));

outArray.append(sizes); //insert theoretical length of message
outArray.append(datas); //insert message

0

Решение

(Я автор амф-каст)

Я только что добавил поддержку пакетов AMF3 в amf-cpp. Чтобы использовать его, вы должны создать AmfPacket объект, добавить заголовки (PacketHeader) или сообщения (PacketMessage), а затем сериализовать AmfPacket, Вот быстрый пример (который предполагает что-то вроде using namespace amf; для краткости):

AmfPacket packet;
// first, we construct a simple header in-place
packet.headers.emplace_back(
"SomeHeader", // header name
false, // must understand?
AmfString("Value") // header value
);

// set up the message value
AmfObject object;
// add some properties
object.addSealedProperty("prop", AmfString("val"));
AmfArray content;
content.push_back(object);
// now construct the message in-place
packet.messages.emplace_back(
"com/example/Object.method", // target uri
"/1/onResult", // response-uri
content // value
);

// amf::v8 is a typedef for std::vector<uint8_t>
v8 data = packet.serialize();

Результирующий data Затем объект может быть использован с вашим QDataStream,

В будущем, если вы заметите, что в amf-cpp отсутствует функция, которую вы хотели бы использовать, не стесняйтесь открывать отчет об ошибках в GitHub трекер.

2

Другие решения

Ты можешь использовать QDataStream выводить ваши данные в сетевом порядке байтов.

QDataStream stream(&outArray, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::BigEndian);
stream << (qint16)3; // version
stream << (qint16)0; // header count
stream << (qint16)1; // message count
stream << (qint16)4; // target length
stream << (qint32)0x6e756c6c; // target
stream << (qint16)2; // response length
stream << (qint16)0x2f31; // response
stream << (qint32)data.size(); // message size
stream.writeRawData(data.data(), data.size()); // message data

Я рекомендую переключить весь ваш код ввода-вывода, чтобы использовать QDataStream для взаимодействия с QByteArray, а не записывать каждый байт по отдельности.

0