amf.h中关于 AMFObject 是这样的定义的:

 typedef struct AMFObject
{
int o_num;
struct AMFObjectProperty *o_props;
} AMFObject;

有里面变量可知 o_num 代表 o_props的个数;

在rtmp.c里有这样一段使用在

static int HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
{
AMFObject obj;
AVal method;
AVal method11;
int txn;
int ret = , nRes;
if (body[] != 0x02) /* make sure it is a string method name we start with */
{
//RTMP_Log(RTMP_LOGWARNING, "%s, Sanity failed. no string method in invoke packet", __FUNCTION__);
return ;
} nRes = AMF_Decode(&obj, body, nBodySize, FALSE);
if (nRes < )
{
//RTMP_Log(RTMP_LOGERROR, "%s, error decoding invoke packet", __FUNCTION__);
return ;
}    AMF_Dump(&obj);
   AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method);
  
  .....
  .....
}

在此函数内 AMFObject obj;通过 nRes = AMF_Decode(&obj, body, nBodySize, FALSE); 会对body进行AMF解码相当于给obj进行赋值,然后通过AMF_Dump(&obj) 应该是进行一个解析?(最下面会贴出该函数的源码)

经过AMF_Dump()之后,会获通过 AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method); 获取信令的操作。当然也可以自定义他们的操作,类似于:

static const AVal av_NetStream_Pause_Notify = AVC("NetStream.Pause.Notify");
static const AVal av_NetStream_Play_UnpublishNotify = AVC("NetStream.Play.UnpublishNotify");
//................

下面代码会根据method的内容进行相应的操作。
-----------------------------------------------

扯的有点偏了,这里还是 讲AMFObject 上面的操作经过抓包可以看一下大致的内容:

===================================================

由包里的内容此次信令操作为自定义的“NoticeNotify”,而obj相当于一个容器,里面就有上面标识的3项内容,也就是根据AMFObject 的数据结构可知:

o_num 个数为3 项 o_props 内容。而 o_props 的数据结构为:

typedef struct AMFObjectProperty
{
AVal p_name;
AMFDataType p_type;
union
{
double p_number;
AVal p_aval;
AMFObject p_object;
} p_vu;
int16_t p_UTCoffset;
} AMFObjectProperty;

其中 o_props 里有个“联合”数据结构成员,从上面抓包的内容来看其中的三项,也很好的解释了其中三项的内容。

第一项:type 为string 对应 AVal 类似于 key-value

第二项:type 为Number 对应 double。

第三项:type 也为string 对应 AVal。

这样来看如果想取obj里的内容就比较好取了。

其中obj的成员 o_props 就是一个类似数组,在操作的时候可以 obj->o_props[index];

或者再细一点就是 obj->o_props[index].p_type;

=====================================

总结的比较乱,因为现在对amf还不是很了解,不过对于amf真的可以花些时间去分析一下它的博大精深。

再此贴一下AMF_Dump()的源码:

void
AMFProp_Dump(AMFObjectProperty *prop)
{
char strRes[];
char str[];
AVal name; if (prop->p_type == AMF_INVALID)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: INVALID");
return;
} if (prop->p_type == AMF_NULL)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: NULL");
return;
} if (prop->p_name.av_len)
{
name = prop->p_name;
}
else
{
name.av_val = "no-name.";
name.av_len = sizeof("no-name.") - ;
}
if (name.av_len > )
name.av_len = ; snprintf(strRes, , "Name: %18.*s, ", name.av_len, name.av_val); if (prop->p_type == AMF_OBJECT)
{
//RTMP_Log(RTMP_LOGDEBUG, "Property: <%sOBJECT>", strRes);
AMF_Dump(&prop->p_vu.p_object);
return;
} switch (prop->p_type)
{
case AMF_NUMBER:
snprintf(str, , "NUMBER:\t%.2f", prop->p_vu.p_number);
break;
case AMF_BOOLEAN:
snprintf(str, , "BOOLEAN:\t%s",
prop->p_vu.p_number != 0.0 ? "TRUE" : "FALSE");
break;
case AMF_STRING:
snprintf(str, , "STRING:\t%.*s", prop->p_vu.p_aval.av_len,
prop->p_vu.p_aval.av_val);
break;
case AMF_DATE:
snprintf(str, , "DATE:\ttimestamp: %.2f, UTC offset: %d",
prop->p_vu.p_number, prop->p_UTCoffset);
break;
default:
snprintf(str, , "INVALID TYPE 0x%02x", (unsigned char)prop->p_type);
} //RTMP_Log(RTMP_LOGDEBUG, "Property: <%s%s>", strRes, str);
}

最新文章

  1. seo优化urlrewrite伪静态技术
  2. [LeetCode]444. Sequence Reconstruction
  3. asp.net教程:编译错误同时存在于不同dll中
  4. SPSS数据分析—因子分析
  5. 将pdf文件通过itunes直接拖到ipad的ibooks里面
  6. POJ2763 Housewife Wind(DFS序)
  7. dmp文件导入
  8. [算法练习] UVA 10420 - List of Conquests?
  9. Nginx - Events Module
  10. Android如何在一个线性布局里完美显示两个listview啊?
  11. java Hastable使用
  12. Spring Security-用户密码自定义加密
  13. Linux平台 Oracle 12cR2 RAC安装Part2:GI配置
  14. 记2017问鼎杯预赛的wp---来自一个小菜鸡的感想
  15. Swift 编程杂谈
  16. OO_多项式求导_单元总结
  17. p1209 Barn Repair
  18. Redis 发布与订阅模式
  19. oracle long类型转换成varchar2
  20. caffe安装编译问题-ImportError: No module named google.protobuf.internal

热门文章

  1. Struts06---通配符的使用
  2. Django框架(三)
  3. Spring:org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class
  4. Maven入门:Maven的基本概念
  5. 2017年国内已经开设机器人工程专业(080803T)高校名单
  6. 微信小程序如何在使用wx.request使用cookie
  7. js 获取服务器当前时间
  8. 旧书重温:0day2【9】第六章 攻击c++的虚函数
  9. 解决Chrome关联HTML文件,图标不显示的问题。
  10. ArcGIS Runtime SDK for WPF之测量距离和面积