AMFObject 数据格式浅析
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);
}
AMFObject 数据格式浅析的更多相关文章
- 【原】AMFObject数据格式详解
AMF AMF是Action Message Format(动作消息格式)的简写,它是一种二进制的数据格式.它的设计是为了把actionscript里面的数据(包括Object, Array, Boo ...
- netty5 HTTP协议栈浅析与实践
一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...
- 浅析WebGIS
浅析WebGIS 摘要:随着网络的发展,利用Web公布信息越来越普及化.而地理信息系统(GIS)与网络的结合就产生了万维网地理信息系统(WebGIS),它引起了地理信息公布的新的变革,对实现GIS信息 ...
- 浅析深究什么是SOA?
浅析深究什么是SOA? http://blog.vsharing.com/fengjicheng/A1059842.html 金蝶中间件有限公司总经理 奉继承 博士 阅读提示: 本文探讨SOA概念背后 ...
- 内存管理 & 内存优化技巧 浅析
内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户 ...
- 用Python浅析股票数据
用Python浅析股票数据 本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略. 数据导入 这里将股票数据存储在stockData ...
- 浅析MVC模式与三层架构的区别
浅析MVC模式与三层架构的区别 三层架构和MVC是有明显区别的,MVC应该是表现模式(三个加起来以后才是三层架构中的UI层).三层架构(3-tier application) 通常意义上的三层架构就是 ...
- 浅析 Bigtable 和 LevelDB 的实现
在 2006 年的 OSDI 上,Google 发布了名为 Bigtable: A Distributed Storage System for Structured Data 的论文,其中描述了一个 ...
- 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】
本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...
随机推荐
- 【2018年全国多校算法寒假训练营练习比赛(第五场)-E】情人节的电灯泡(二维树状数组单点更新+区间查询)
试题链接:https://www.nowcoder.com/acm/contest/77/E 题目描述 情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡 ...
- LeetCode OJ:Intersection of Two Linked Lists(两个链表的插入)
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- 【SQL查询】查询列中使用条件逻辑_case when then end
select x.范围, count(*) from (select t.ename, case when t.sal <= 100 ...
- QGrapicsScene类
概述 QgraphicsScene类为管理大量的2D图形item提供了一个管理界面,做为item的容器,它配合使用QgraphicsView使用来观察items,例如线,矩形,文本或者自定义的item ...
- 使用BloomFilter布隆过滤器解决缓存击穿、垃圾邮件识别、集合判重
Bloom Filter是一个占用空间很小.效率很高的随机数据结构,它由一个bit数组和一组Hash算法构成.可用于判断一个元素是否在一个集合中,查询效率很高(1-N,最优能逼近于1). 在很多场景下 ...
- Sphinx 匹配模式
所谓匹配模式就是用户如何根据关键字在索引库中查找相关的记录. SPH_MATCH_ALL, 匹配所有查询分词(默认模式); 如“手机配件”,不匹配 “我有一部手机”,但可以匹配 “手机坏了,需要找配件 ...
- 抛弃Https让Cas以Http协议提供单点登录服务
本文环境: 1.apache-tomcat-7.0.50-windows-x86 2.cas-server-3.4.11 3.cas-client-3.2.1 将cas-server-webapp-3 ...
- linux离线搭建Python环境及安装numpy、pandas
1.安装python2.7.3 Cent OS 6.5默认装的有python2.6.6,需要重新安装python2.7.3下载地址:https://www.python.org/downloads/s ...
- matlab算法转为c语言注意事项
matlab算法转为c语言后,影响c语言效率的关键在于multiword的产生,基于此会有multiword加减法和乘除法,极大消耗资源,减少甚至消除multiword很重要,需注意的是:算法中尽量减 ...
- Note: log switch off, only log_main and log_events will have logs!
真机(华为c8813)在Eclipase上测试,打不出logcat信息,只有这样的一句话:Note: log switch off, only log_main and log_events will ...