这是[手把手一起学live555]的第11篇(按这个序号看,请找正确顺序看)。
live555工程在我的gitee下(doc下有思维导图、drawio图):https://gitee.com/lure_ai/live555/tree/master
章节目录链接
0.前言——章节目录链接与为何要写这个?
https://blog.csdn.net/yhb1206/article/details/127259190?spm=1001.2014.3001.5502
学习demo
live555mediaserver.cpp
学习线索和姿势
1.学习的线索和姿势
网络编程
流媒体的地基是网络编程(socket编程)。
[网络编程学习]-0.学习路线。
绘图规则
本文的对象图和思维导图遵守的规则详见:
2.绘图规则
非阻塞服务端网络编程流程
socket创建、bind、listen、select、accept、select、recv/send-close。
rtsp协商流程
option、describe、setup、play、pause、teardown、get parameter、set parameter。
本节内容和目标
(1)如何解析rtsp请求报文的
(2)思维导图绘制
(3)对象图绘制
正式开始
上节解决了巧妇的“米”,也就是得到了完整的rtsp请求报文,这节来看下巧妇是如何做“炊”的?——本节学习下live555是如何解析完整rtsp请求报文的。
还记得上节的一个图么,如下
其思维导图如下:
从思维导图可知:
(1)图中红框里的parseRTSPRequestString,就是解析rtsp请求报文的地方。
(2)parseHTTPRequestString解析http协议处理。http这块暂时不说了。
回顾看下rtsp请求报文的特点,如《rtsp协议格式解析》一文所述(讲的太棒了,膜拜),截图如下
可以看到请求报文分为请求行、首部行——一般没有实体,就认为没有实体了。
如何解析请求行
请求报文的开始行称为请求行。如下图举个例子看parseRTSPRequestString是如何解析它的。
图10-1 请求行解析示意图
如图10-1,这是请求行:
图中(1)是请求行的通用抽象,可以看到请求行分成了分成了3大部分:请求方法、url、版本。
图中(2)是举了一个URL为例子:rtsp://192.168.146.1:8554/…/…/test.264, 版本为RTSP/1.0。
图中(3)parseRTSPRequestString中解析请求行的过程,把局部变量标识画出来了。
请求方法解析
parseRTSPRequestString中解析请求方法的代码片段如下:
先是找到非空格的位置,然后存放请求方法,如图10-1,其请求方法后面是空格,很好找。
解析URL文件名及相对路径
这部分对应图10-1中(3)中的i的位置,这就找到了url的文件路径的起始位置,即i指向了rtsp://192.168.146.1:8554/…/…/test.264中//后面的第1个/的位置。
接着要解析url中的文件名,如下图也很简单
就是根据请求行最后的RTSP/来倒推url的结尾位置即k指向rtsp://192.168.146.1:8554/…/…/test.264中的4的位置,然后再倒推到倒数第一个/的位置用k1来保存,取出k1+1到 k之间的字符串,即是文件名test.264,存放起来。然后再倒推到i,取出i+1到k1-1之间的字符串,就找到了相对路径,即…/…。然后解析。接着i+7指向了版本号RTSP/1.0中的1的位置——可以看到它这个很是严格,URL后面必现跟的是1个空格,如果多一个空格就会有问题。
请求行解析完毕。
注意,
(1)请求行出现失败,就是失败。也是必不可少的、严格的。
(2)parseRTSPRequestString出参urlPreSuffix和urlSuffix是什么意思?
这就涉及到live555把url进行了自己的格式理解,如下
rtsp://ip:port/urlPreSuffix/urlSuffix
对于rtsp://192.168.146.1:8554/…/…/test.264,经过parseRTSPRequestString解析后出参urlPreSuffix是"…/…/…/test", urlSuffix是"backkom.mkv"。
接下来,整个的rtsp协议流程的url如下:
OPTIONS rtsp://192.168.145.1:554/…/…/…/test/backkom.mkv RTSP/1.0
DESCRIBE rtsp://192.168.145.1:554/…/…/…/test/backkom.mkv RTSP/1.0
SETUP rtsp://192.168.145.1/…/…/…/test/backkom.mkv/track1 RTSP/1.0
SETUP rtsp://192.168.145.1/…/…/…/test/backkom.mkv/track2 RTSP/1.0
PLAY rtsp://192.168.145.1/…/…/…/test/backkom.mkv/ RTSP/1.0
可以看到option和describe的url是一样的,其他流程不一样,那如何处理的呢?
describe是这样的,把urlPreSuffix和urlSuffix拼接到一起,成为key值。具体作用见后面的describe学习。
那么其他流程怎么找到这个key值的?自然只需要urlPreSuffix这个就行了。
如何解析首部行
如下截图,首部行也好解析,就是 “首部行字段” + “:” + “空格” + “值” + “结束符\r\n” 。
必不可少的是CSeq字段,这个是序号,由双方为何,同一次请求和响应的CSeq要一样,这个也是保证。其他首部字段是可选的。
解析CSeq首部字段
该字段是必须有的,如果没有也直接报解析失败。解析也很简单,直接粗暴匹配CSeq字段。
其他首部行字段解析
其他首部行字段解析,有"Session:“、有"Content-Length:”,解析方法和CSeq一样直接匹配,但是这2个字段是可选的,没有的话不会报错。如下
注意,
(1)目前只支持这3个首部字段解析,
(2)解析方法流程一样,完全可以优化为一个函数——直接传参查找得了,没必要重复三次一样的循环——优化点。
(3)其中"Content-Length:"就是实体的长度,但是请求报文是没有的——除非你自己私自增加。
小结
本节学习了parseRTSPRequestString中解析请求报文的通用流程,OPTIONS/DESCRIBE等等报文请求全部适用该流程。