2014-01-27 2 views
0

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

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

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

Так я создал

typedef unsigned int u16; 

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

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()); 

В результате в данном я только что первый вставленный векторе (БУФЫ).

// edit Я достиг некоторого прогресса.

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

У вас остались вопросы? Я думаю, вы хорошо объяснили, что вы пытаетесь сделать; но я не понимаю, в чем проблема. – JeffryHouser

+0

Хорошо AMF (0 или 3) обычно является просто кодировкой данных. Особенно каждое сообщение AMF3 обернуто в сообщение AMF0, которое содержит контент AMF3 в специально выделенной части сообщения AMF0. В полезной нагрузке AMF3 обычно Adobe напрямую не кодирует вашу полезную нагрузку. Обычно он заключен в сериализованные командные объекты AMF3. Однажды я сделал полную обратную разработку связи AMF3. К сожалению, я в настоящее время не могу найти этот документ ... даст ему еще один вид, когда я буду дома. –

+0

@ Reboog711 Я описал код, я просто не знаю, почему buffermain содержит только первое вставленное значение (buf), оно должно содержать buf, buf2 и buf3. –

ответ

2

(я автор amf-cpp)

Я только что была добавлена ​​поддержка пакета AMF3 в АИФ-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 issue tracker.

+0

@Ventero У меня есть проверка на AMF3-пакет с использованием Charles. И попытка воссоздать пакет, используя вашу библиотеку amf-cpp. Благодаря вашей работе, в первую очередь. Но я нахожу, что то, что я создал, отличается от захваченного Чарльзом. У вас есть хороший пример вашей библиотеки? Ваш ответ на этот вопрос не говорит мне о вашей библиотеке. –

+0

И когда я отправляю его на сервер с помощью libcurl, я получаю это сообщение с сервера./3/onStatus Ошибка в коде: \t Код? На сервере произошел необработанный сбой. java.lang.NullPointerException # Server.Processing –

+0

@JoshuaSon Поскольку эта библиотека все еще находится в тяжелом развитии, и API по-прежнему может быть изменен, у меня пока нет документации. Вы можете создать отчет об ошибках в трекерах Github (https://github.com/Ventero/amf-cpp/issues/) с более подробной информацией о том, какой пакет вы пытаетесь воссоздать? Кроме того, я не уверен, как здесь работает libcurl, поскольку сериализованное сообщение должно быть отправлено через сокет. – Ventero

0

Вы можете использовать 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 вместо выписывая каждый байт по отдельности.

Смежные вопросы