趣谈网络协议笔记-二(第十六讲下)

趣谈网络协议笔记-二(第十六讲下)

流媒体协议:如何在直播里看到美女帅哥?


自勉

  • 我爱你,与你有何相干?毁灭你,又与你有何相干?——《三体》
  • 你的无畏来源于无知。——《三体》

前言

的确有两天没有写这类的文章了,想想还是需要继续下去,毕竟这是我对于自己未知的事情的探索之路。
以前,当我看到别人说XXX太简单的时候,总会有一张想去反驳的冲动,因为我对于自己的要求就是不断探索,对于未知永远存在一种渴求和敬畏之心。
但是最近,我感觉这种冲动,渐渐变得缓和了。我逐渐能够控制自己了,很多时候,无知者真的是很可笑的,对于我自己也是。
我对于自己的要求就是,当我向别人讲述一些道理的时候,我会保证,自己对于这个道理是清楚的,而不是一知半解的,仅仅是拿从百度上搜索过来的所谓的高大上的词汇来忽悠人,这不仅仅是浪费了自己的时间,同时也浪费了别人的时间。
我记得,央视有一档节目,叫《开讲啦》,会请各个领域的成功人士来鼓励新一代的孩子。有一次就请来了马云,有一个刚刚进入大学的学生就问,”我愿意用我的青春来换取你所有的财富,你愿意吗?我今年20岁“。
马云说,当然愿意,很多人仅仅是笑笑。但是你细想,马云回答的其实很中肯,为什么呢?马云付出的是财富,换取来的是时间。但是对于任何人来说,当财富超过一个值时,其实仅仅是一个数字了,一个人能享受的极限其实真的是很有限的。穷人和富人最公平的地方是什么,是时间,给与马云时间,以马云的社会地位,金钱其实不是问题。


正文

[image:938D10CF-4661-4FC6-BF6E-8F4D6C34456F-305-000053B257DA2C36/b8f215697ce950005a532d3be341f570.jpg]

[image:6F89E761-98BA-4C3A-91F0-53466DBD02FC-305-000053B37E6E878A/42dcd0705e3b1bad05d59fd9d6707d60.jpg]

读到这章,分层的模型以及其作用其实已经呼之欲出了。对于RTMP(real time messaging protocol)这类处于TCP/IP四层分层结构的应用层的协议。其本身的开发其实不应该对于传输层的具体操作具有任何可知性,你要知道的一切仅仅是,你的下一层即TCP层,是仅仅依靠你所提供的目的地ip,端口等基本信息就能将你委托给他的数据传输到目的地,这样就足够了。不然,所谓的分层,所谓的解耦就完全没有意义!

但是,这样也带来一些问题,tcp协议进行三次握手时,仅仅是尽可能确保两者之间的网络连接没有问题,数据的传输没有问题,但是如果我需要知道在应用层需要的一些协议对方支不支持这类的问题,其实仅仅凭借TCP协议是没有办法的,因为基于解耦,复用的目的实现了分层嘛。
那么该怎么办呢?就只能在应用层再次进行所谓的握手操作了,这里因为用的表述和tcp层握手操作一样,所以其实我一开始也绕进去了。
[image:017B9201-74B0-4155-85AA-A45DC871F173-305-000053B51F98E221/de6301500d02c5afa3e6c6f5fa47bac7.jpg]

这张图其实有问题的,s0发送的时机我感觉有问题。
RTMP协议在TCP协议通过握手建立了连接之后,由客户端发起握手请求c0(为什么不是服务器发起呢?服务器毕竟要处理所有用户的请求,既然无论谁请求达成的效果差不多,那么就让活少一点的客户端发起就行了),请求的内容为客户端支持的RTMP协议版本,毕竟沟通的基础就是语言相通,你说英文我说中文,这个肯定就不行。然后客户端不管服务器有没有回复,直接再发送自己的时间戳c1。
然后服务器收到了客户端的请求c0,然后看看自己支不支持,如果不支持,就不鸟他,直接断开连接,反正TCP协议自己会有消息送达的回复机制。如果支持,就返回自己的版本号s0(唔,这里感觉有一些问题,为什么还需要返回自己的版本号啊,既然确定版本支持了,直接返回OK就行了嘛,难道像HTTP协议一样,客户端在请求的时候还会发送多个支持的协议版本让服务器选择?),然后再发送自己的时间戳给客户端s1。
那么这里为什么要发送时间戳呢?说到底还是需要协调相对时间的统一,因为很有可能,客户端和服务器所设置的系统时间是有区别的,如果不进行统一,我怎么知道你需要的视频到底是哪个时间点的?但是,应用要求客户强行统一时间是绝对不可行的,所以就希望采用类似互发时间戳的方式来设置两者的相对时间。后续的信息传输仅仅需要同步相对的时间即可。

上一个章节说过,在处理直播的数据时,会将每一帧的图片数据分割成片,块,子块来进行压缩,从而构成一个个NALU(network abstraction layer unit)。
[image:87D391D3-FBEE-4214-8F9A-7EF9ED738D0D-305-000053B74FDC2A79/1a97a0b90c2304cbdf22a2bc8a8ce94b.jpg]

一般情况会将这个数据存储在如下结构中,一个message就表示一个NALU,但是受限于MAC层传输数据的限制,需要对message进行再次的分割传输,这个传输的基本单位就是chunk。
[image:49B8803A-AB03-4279-AFCE-6D0234174C0D-305-000053B895A91F51/41abff0d11198fcf8b8308f3222b8c2f.jpg]

在RTMP握手成功后,RTMP是如何进行推流和拉流的操作的呢?先建立连接!
我真的佩服RTMP协议的设计者,我感觉他真的应该好好学学TCP协议,学学人家是怎么通过三次握手就能建立起可靠连接的。
[image:56B2CF51-BB25-47E3-B314-2D2385ADC4C1-305-000053BDDB82EB5C/14221e482876b0b243f5213c7a1cc62e.jpg]

客户端先发送建立连接的请求,服务端接收到之后发送窗口大小和带宽给客户端(应该是客户端需要基于这个来调整发送的速度)。
然后客户端接收到信息后发送自己的窗口大小给服务器(因为要同时考虑客户端拉流和推流的需要!),服务端收到后返回“收到”给客户端,至此连接建立完毕。
连接建立完毕后,客户端向服务器发送构建流的请求,服务器收到后回复“收到”给客户端,至此,流通道创建成功。
之后,客户端向服务器发送拉流请求,服务器收到后会先发送“收到”给客户端,然后就通过流通道开始向客户端进行流数据的传输。
拉流和推流的请求流程其实差不多。
[image:4A9CBB40-2DDF-447C-8602-D70A7C72879B-305-000053C0A8E5A468/52d2e201f87462bc3afed8ce4d743aee.jpg]

最后是直播网络架构,如下,基本没有什么特别需要留意的。
[image:78F00F02-E7C7-4003-8DB9-0B87ACFFD8CC-305-000053BF69374C1A/6cdbe17d580f46d60d5f6380262834db.jpg]

扫描二维码关注公众号,回复: 11597002 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_31433709/article/details/108046400