试图制作AMF3数据包

Trying to make AMF3 Packet

本文关键字:AMF3 数据包      更新时间:2023-10-16

我正在尝试制作AMF数据包。我正在使用https://github.com/ventero/AMF-CPP C AMF3的实现,但并不包含所有需要的变量。AMF0文档正在描述如何构建AMF数据包(http://download.macromedia.com/pub/labs/amf/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

(我是AMF-CPP的作者)

我刚刚向AMF-CPP添加了AMF3数据包支持。要使用它,您必须创建一个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();

然后可以与您的QDataStream一起使用所得的data对象。

将来,如果您注意到AMF-CPP缺少您想使用的功能,请随时在GitHub Diseage Tracker上打开错误报告。

您可以使用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

我建议将所有I/O代码切换以使用QDataStream与QByTearray接口,而不是单独编写每个字节。