﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Apollo Fang's Blog-随笔分类-Protocol</title><link>http://www.cppblog.com/scorpio/category/20161.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 31 Oct 2012 09:36:23 GMT</lastBuildDate><pubDate>Wed, 31 Oct 2012 09:36:23 GMT</pubDate><ttl>60</ttl><item><title>RTMP协议 - Chunk</title><link>http://www.cppblog.com/scorpio/archive/2012/10/31/194128.html</link><dc:creator>Apollo Fang</dc:creator><author>Apollo Fang</author><pubDate>Wed, 31 Oct 2012 09:09:00 GMT</pubDate><guid>http://www.cppblog.com/scorpio/archive/2012/10/31/194128.html</guid><wfw:comment>http://www.cppblog.com/scorpio/comments/194128.html</wfw:comment><comments>http://www.cppblog.com/scorpio/archive/2012/10/31/194128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/scorpio/comments/commentRss/194128.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/scorpio/services/trackbacks/194128.html</trackback:ping><description><![CDATA[<p style="text-indent:21.0pt"><span style="font-family:新宋体">KEY : Message / Chunk / Stream</span></p>  <p style="text-indent:21.0pt"><span style="font-family: 新宋体; text-indent: 21pt; ">Rtmp中,一个Message通常是分割成多个Chunk进行传输的.每个Chunk通常包含有1~12个字节的头部(该部分与完整的协议不是十分符合).</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">因为</span><span style="font-family:新宋体">Rtmp是基于TCP协议的,所以在Rtmp传输过程中, Chunk头部会根据实际情况使用简化的头部(12字节的头部是完整的头部,8/4/1字节的头部是根据实际情况简化的).</span></p>  <p style="background:#D9D9D9"><span style="font-family:新宋体">一</span><span style="font-family:新宋体">. Chunk头部的简化规则</span></p>  <p>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="text-indent: 21pt; font-family: 新宋体; ">说明</span><span style="text-indent: 21pt; font-family: 新宋体; ">:以上的"------"为6bit的ChunkId</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">1 . 00------头部</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">在传输开始</span><span style="font-family:新宋体">,的第一个Chunk头部通常使用(00------)格式,包含完整的头部信息,依次包含:时间戳,Message长度,Message类型1B,StreamId1B. 这些信息在程序中是需要保留的.以便后面简化的头部,可根据该头部完善信息.</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">2 . 01------头部</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">当发送多个相关的</span><span style="font-family:新宋体">Message时,Chunk的头部通常使用(01------)开始, 后面追加StreamId,Message类型和Message长度三个字段,这些字段与前一个Chunk的信息保持一致.例如,当交错的发送Video/Audio Message,它们属于同一个StreamId,但其他字段都发生了变化.</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">3 . 10------头部</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">当由一个</span><span style="font-family:新宋体">Message拆分成的连续的两个Chunk的时间戳发生了变化时(尤其是Video/Audio Message),例如,一个Video Message中前一个Chunk和下一个Chunk的时间戳或时间戳增量不一致,后面的Chunk头部会以(10------)开始, 再追加一个3字节的时间戳字段即可.</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">4 . 11------头部</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">当一个</span><span style="font-family:新宋体">Message过长,需要由多个连续的Chunk进行发送时,Chunk的头部通常会以(11------)开始, 没有其他附加字段,所有相关字段与前一个Chunk保持一致.</span></p>  <p>&nbsp;</p>  <p style="background:#D9D9D9"><span style="font-family:新宋体">二</span><span style="font-family:新宋体">. 关于ChunkId和StreamId</span></p>  <p><br /></p>  <p style="text-indent:21.0pt;background:#D9D9D9"><span style="font-family:新宋体">1 . StreamId的使命</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">一个</span><span style="font-family:新宋体">StreamId通常用以完成某些特定的工作. 如使用Id为0的Stream来完成客户端和服务器的连接和控制,用Id为1的Stream来完成Stream的控制和播放等工作.</span></p>  <p style="text-indent:21.0pt;background:#D9D9D9"><span style="font-family:新宋体">2 . ChunkId的使命</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">一个</span><span style="font-family:新宋体">ChunkId通常会完成某个特定的工作. 比如说系统保留的ChunkId为2的就只是用于完成对Stream的控制. 在该通道上,服务器和客户端可以对Stream的具体属性进行设置和交互.如创建一个Stream,告知Stream结束,设定Stream的带宽,设定Chunk大小,终止Message等.这里对Stream的控制不是针对某个Stream的,而是全局的.</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">再比如</span><span style="font-family:新宋体">,使用ChunkId8对播放进行控制.客户端发送"play"命令,服务器也会通过ChunkId8这个通道告知客户端播放的状态,如告知客户端播放开始,播放完成等信息.服务器使用ChunkId5进行媒体数据的传送,如果客户端需要针对这些数据对服务器应答,也要使用该通道.</span></p>  <p style="text-indent:21.0pt;background:#D9D9D9"><span style="font-family:新宋体">3 . ChunkId和StreamId的关系</span></p>  <p style="text-indent:21.0pt"><span style="font-family:新宋体">ChunkId和StreamId的关系目前并不明了,但通常情况下某一个ChunkId会在固定的StreamId中完成相应的工作. 比如ChunkId2对Stream的相关属性进行控制,这些控制的消息必须在StreamId0中完成.也就是说ChunkId2和StreamId0指定了服务器和客户端对Stream控制的以个对话通道.</span></p><img src ="http://www.cppblog.com/scorpio/aggbug/194128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/scorpio/" target="_blank">Apollo Fang</a> 2012-10-31 17:09 <a href="http://www.cppblog.com/scorpio/archive/2012/10/31/194128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>