Action Message Format - AMF0

摘要


Action Message Format (AMF) 是一种简洁的二进制格式,通常用于序列化ActionScript object graphs(对象图?不会翻译)。一旦序列化,AMF编码的对象图可用于会话之间持久化以及检索应用程序的公共状态,或者允许两个端通过强类型数据的交换进行通信。

AMF 0 Data Types


下方是AMF0的16种类型的markermarker位占用一个字节长度,用于描述AMF中某种数据类型。

marker value remark
number-marker 0x00
boolean-marker 0x01
string-marker 0x02
object-marker 0x03
movieclip-marker 0x04 reserved, not supported
null-marker 0x05
undefined-marker 0x06
reference-marker 0x07
ecma-array-marker 0x08
object-end-marker 0x09
strict-array-marker 0x0A
date-marker 0x0B
long-string-marker 0x0C
unsupported-marker 0x0D
recordset-marker 0x0E reserved, not supported
xml-document-marker 0x0F
typed-object-marker 0x10

抓包分析


因为AMF0采用的是 big endian (network) byte order,所以先简单看看什么是big endian

int val = 0x1234;

big endian:
低地址  0------->1------->2   高地址
        +--------+--------+
        |  0x12  |  0x34  |
        +--------+--------+
little endian:
        +--------+--------+
        |  0x34  |  0x12  |
        +--------+--------+
  1. Number
number-type = number-marker DOUBLE

Action Message Format - AMF0_第1张图片
Number
如上图所示,红框内的是 Numbermarker0x00,紫框是 Number的数值,为 40 08 00 00 00 00 00 00,我的电脑是 little endian的所以我在内存里面看到的相应的数值是 00 00 00 00 00 00 08 40
我们可以看一下 rtmpdump的实现

char *AMF_EncodeNumber(char *output, char *outend, double dVal)
{
    unsigned char *ci, *co;
    ci = (unsigned char *)&dVal;
    co = (unsigned char *)output;
    co[0] = ci[7];
    co[1] = ci[6];
    co[2] = ci[5];
    co[3] = ci[4];
    co[4] = ci[3];
    co[5] = ci[2];
    co[6] = ci[1];
    co[7] = ci[0];
}
  1. Boolean
boolean-type = boolean-marker U8 ; 0 is false, <> 0 is true

Action Message Format - AMF0_第2张图片
Boolean
如上图所示,红框内的是 Booleanmarker0x01,紫框是 Boolean的数值,为 0x01,理论上只要非零就是 true
rtmpdump的实现

char * AMF_EncodeBoolean(char *output, char *outend, int bVal)
{
  *output++ = AMF_BOOLEAN;
  *output++ = bVal ? 0x01 : 0x00;
  return output;
}
  1. String
string-type = string-marker UTF-8

Action Message Format - AMF0_第3张图片
String
如上图所示,红框内的是 Stringmarker0x02,绿框是字符串的长度,值为 0x0008,紫框是 String的值,为 onStatusASCII码。
rtmpdump的实现

char *AMF_EncodeString(char *output, char *outend, const AVal *bv)
{
 *output++ = AMF_STRING;
  output = AMF_EncodeInt16(output, outend, bv->av_len);
  memcpy(output, bv->av_val, bv->av_len);
  output += bv->av_len;
  return output;
}
  1. Object
object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
anonymous-object-type = object-marker *(object-property)

Object类型除了可以包含其他类型之外,也可以包含Object类型。

Action Message Format - AMF0_第4张图片
image.png
Object是以 Object-End结束的,值为 0x000009

Thanks


  1. rtmpdump,简直是入门引路者

最终目标是实现RTMP协议。还好前方有大量牛人实现过,感觉造轮子的时候,可以抄一下=。=
简单地实现了一下,代码地址->amf0

你可能感兴趣的:(Action Message Format - AMF0)