1、live555学习之RTSP连接建立以及请求消息处理过程live555 学习之 RTSP 连接建立以及请求消息处理过程1,RTSP 连接的建立过程RTSPServer 类用于构建一个 RTSP 服务器,该类同时在其内部定义了一个 RTSPClientSession 类,用于处理单独的客 户会话。首先创建 RTSP 服务器 (具体实现类是DynamicRTSPServer) ,在创建过程中,先建立Socket(ourSocket)在TCP的554端口进行监听,然后把连接处理函数句柄(RTSPServer: incomingConnectionHandler) 和 socket 句柄传给 任务调度
2、器 (taskScheduler)。任务调度器把 socket 句柄放入后面 select 调用中用到的socket句柄集(fReadSet)中,同时将 socket句柄和 incomingConnectionHandler 句柄关联起来。接着,主程序开 始进入任务调度器的主循环( doEventLoop ),在主循环中调 用系统函数 select 阻塞,等待网络连接。当 RTSP 客户端输入 (rtsp:/192.168.1.109/1.mpg) 连接服务器时,select返回对应的scoket,进而根据前面保存的对应 关系,可找到对应处理函数句柄,这里就是前面提到的incomingConn
3、ectionHandler 了。在始对这个客户端的会话进行处理。具体分析如下:DynamicRTSPServer:creatnew() :1.调用继承自 RTPSever:setUpOurSocket:1.调用 GroupsockHelper 的 setupStreamSocket创建个 socket 连接,并绑定,2.设置 socket 的发送缓存大小,3.调用 listen 开始监听端口,设置同时最大能处理连接数 LISTEN_BACKLOG_SIZE=20 ,如果达到这个上限则client 端将收到 ECONNERREFUSED 的错误4.测试绑定端口是否为 0,为 0 的话重新绑定断口
4、,并返回系统自己选择的新的端口。5.返回建立的 socket 文件描述符2.调用自己和 RTPSever的构造函数:RTPSever构造函数:1.用一个 UsageEnvironment 对象的引用构造其父类Medium2.设置最大等待回收连接时间reclamationTestSeconds,超过这个时间从客户端没有 RTSP命令或者 RTSP 的 RR 包则收回其 RTSPClientSession3.建立一个HashTable (实际上是一个BasicHashTable),fServerMediaSessions 指向这个表。4.调用参数 UsageEnvironment 对象 env 的
5、成员 ,一个TaskScheduler 指针所指对象(实际就是一个BasicTaskScheduler 对象)的成员函数turnOnBackgroundReadHandling() :1.调用一个 HandlerSet:assignHandler() 创建个Handler,把socketNum【此处为服务器监听的 socket描述符】和处理函数RTSPServer:incomingConnectionHandler() ,还有指向RTS PSever的指针绑定在一起。incomingConnectionHandler 作用:1.调用 accept 返回服务器与客户端连接的 socket 描述符
6、2.设置客户端描述符为非阻塞3.增加客户端 socket 描述符的发送缓存为 50*10244.为此客户端随机分配一个sessionId5.用客户端 socket 描述符clientSocket,sessionld,和客户端地址 clientAddr 调用creatNewClientSession 创建一个 clientSession。2,请求消息处理过程上节我们谈到RTS P服务器收到客户端的连接请求,建立了 RTSPCIientSession 类,处理单独的客户会话。在建立clientSocket )和 RTSP 请求处理函数句柄RTSPClientSession:incomingRequ
7、estHandler 传给任务调度 器,由任务调度器对两者进行一对一关联。当客户端发出RTSP请求后,服务器主循环中的select调用返回,根据socket句柄找到对应的 incomingRequestHandler ,开始消息处理。先进行消息的解析。RTS PCIientSession:RTS PCIientSession()构造函数:1.重置请求缓存2.调用 envir().taskScheduIer().turnOnBackgroundReadHandIing() ,这 次 socketnumber 为客户端 socket 描述符这次的处理函数是RTSPServer:RTSPCIient
8、Session:incomingRequestHandIer()RTSPServer:RTSPCIientSession:incomingRequestHandIer():调用 handIeAIternativeRequestByte1(uint8_trequestByte):1.fRequestBufferfRequestBytesAIreadySeen=requestByte;把请求字符放入请求缓存 fRequestBuffer2.调用 handleRequestBytes(1) 处理请求缓handleRequestBytes(int newBytesRead):1.调用 noteLive
9、ness() 查看请求是否到期 ,如果服务器的 reclamationTestSeconds> 0 ,调用taskScheduler 对象的 rescheduleDelayedTask 函数:参数为( fLivenessCheckTask,fOurServer.fReclamationTestSeconds*10 00000,(TaskFunc*)livenessTimeoutTask, this )其中livenessTimeoutTaskO函数作用是删除 new出来的 clientSession.1.调用unscheduleDelayedTask(TaskToken&prev
10、Task):从 DelayQueue 中删除prevTask 项, prevTask 置空 .2.调用scheduleDelayedTask(int64_t microseconds,TaskFunc* proc, void*clientData) :1.创建一个 DelayInterval对象 timeToDelay,用 microseconds 初始化。2.创建一个AlarmHandler 对象,用 proc, clientData, timeToDelay 初始化3.调用fDelayQueue.addEntry(), 把这个 AlarmHandler 对象加入到延 迟队列中4.返回 Al
11、armHandler 对象的 tokenlong 类型 的指针2.如果请求的的长度超过请求缓存可读长度 fRequestBufferBytesLeft ,结束这个连接。3.找到请求消息的结尾: 。4.如果找到消息结尾,调用RTS PServer:RTS PCIientSession:handleRequestBytes()值得关注此函数 把请求字符串转换成命令各部分包括:cmdName 方法 , urlPreSuffixurl 地址 , urlSuffix 要读取的 文件名,sceq消息的Cseq,否则函数返回需要继续从连接中读取请求。分别存入对应的数组。OPTIONS ,PLAY , PAU
12、SE ,理对应的 cmdName: xxx 此处实现了:DESCRIBE , SETUP , TEARDOWN ,GET_PARAMETER , SET_PARAMETER其中 PLAY , PAUSE , GET_PARAMETER ,SET_PARAMETER 调用 handleCmd_withinSession (cmdName,urlPreSuffix, urlSuffix,cseq,(char const*)fRequestBuffer);6.清空 RequestBuffer比如: 消息解析后, 如果发现客户端的请求是 DESCRIBE 则 进入 handleCmd_DESCRIBE
13、 函数。 RTSP 服务器收到客户端 的 DESCRIBE 请求后,根据请求URL(rtsp:/192.168.1.109/1.mpg) ,找到对应的流媒体资源, 返回响应消息。 live555 中的 ServerMediaSession 类用来处理 会话中描述,它包含多个(音频或视频)的子会话描述(ServerMediaSubsession)。根据客户端请求 URL的后缀(例如是 1.mpg), 调用成员函数DynamicRTSPServer:lookupServerMediaSession 查找对应的 流媒体信息 ServerMediaSession。(根据 urlSuffix 查找)。如
14、果 ServerMediaSession 不存在,查找文件是否存在,若文 件不存在,则判断 ServerMediaSessionsmsExists)是否存在,如果存在则将其 remove (调用removeServerMediaSession 方法)。但是如果本地存在 1.mpg文件,则根据文件名创建一个新的 ServerMediaSession (调 用 createNewSMS 方法,若在该方法中找不到对应的文件扩 展名,则将返回 NULL )。如果通过 lookupServerMediaSession 返回的是 NULL ,则向客 户端发送响应消息并将 fSessionIsActive
15、置为 FALSE ;否则, 为该session组装一个SDP描述信息(调用 generateSDPDescription 方法,该方法在 ServerMediaSession类中),组装完成后,生成一个 RTSP URL (调用rtspURL方 法,该方法在 RTS PServer类中)。在创建 ServerMediaSession 过程中,根据文件后缀 .mpg ,创 建媒体 MPEG-1or2 的解复用器(MPEG1or2FileServerDemux) 。再由MPEG1or2FileServerDemux 创建一个子会话描述MPEG1or2DemuxedServerMediaSubsession 。最后由ServerMediaSession完成组装响应消息中的 SDP信息(SDP组装过程见下面的描述) ,然后将响应消息发给客户端,完 成一次消息交互。RTSP 服务器处理客户端点播的基本流程处理连接请求的基本流程:l Step 1:与客户端建立 RTSP 连接(调用incomingConnectionHandler 方法),创建 ClientSession 并关联fClientS
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1