这是[手把手一起学live555]的第7篇(按这个序号看,请找正确顺序看)。
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.绘图规则
本节内容和目标
(1)TCP非阻塞服务端网络编程流程传输数据节点——重复select-recvfrom/send(非阻塞服务网络编程流程:socket创建、bind、listen、select、accept、select、recvfrom/send、close)
(2)思维导图绘制
(3)对象图绘制
正式开始
5.live555mediaserver-accept已经追踪到了accept流程,本节追踪select、recv/send流程。
还记得上一节讲的目前链表中有3个了——一个是链表头结点(哨兵-不保存任何数据),一个是服务端监听socket,一个是客户端已链接socket。上一节的链表图搬来如下:
main中调用的BasicTaskScheduler0::doEventLoop是个while循环,它循环调用BasicTaskScheduler::SingleStep——本节说的select就在这——select就这一个地方——到如今的阶段,它已经是同时监听服务端监听socket、客户端已链接socket了。
来看下recvfrom在哪里。
知识点:recv和recvfrom
这个属于TCP和UDP网络编程范畴,不懂的可以看下我的学习路线或者网络搜相关知识。在此只简略讲下得了:recv一般用在TCP,recvfrom一般用在UDP。recvfrom比recv多了2个参数用以获取客户端IP地址信息——他可以用在TCP替换recv——但是accept的时候可以获取到客户端IP地址信息,这就多余了——这个我想是为了兼容UDP?后续再看。
依然以之前VLC拉流为例,现在VLC下发rtsp报文数据到服务端了,然后服务端select监听到了已连接客户端socket,然后匹配链表队员,并执行对应响应方法。思维导图如下:
如上图所示,客户端与服务端之间传输的就是rtsp协议、rtp包等了——这些我们先不谈,它们整体传输流程就是重复的select已链接客户端socket然后执行如下方法:
GenericMediaServer::ClientConnection::incomingRequestHandler(void* instance, int /mask/)
这个方法最终调用到RTSPServer::RTSPClientConnection::handleRequestBytes(bytesRead),它是在这里是处理这些rtsp协议、rtp数据的地方——我现在只关注网络编程线索,上图可知它是通过recvfrom取出客户端发送过来的数据的,并通过send传回响应数据给客户端的。
如下图,是recvfrom所在:
如下图,是send所在
那么整个传输过程就是重复的select-recvfrom/send,如果碰到异常了就close这个socket,如下图。
这close套接字也是支持的很全面,windows下,vxworks,unix下都有。
send是处理要数据服务端会响应VLC客户端的。如何处理如何响应暂且不讲。
close也没必要详细讲解——异常关闭或者teardown关闭得了呗。
到此,本节的select-recvfrom/send-close也是找到了,网络编程线索告一段落。——第1阶段、第1条线索暂时讲解到这里,接下来就要进入第2阶段第2条线索了——rtsp协议线索,在这之前有必要总结下,所以下一节是总结。