1,RTSP连接的建立过程RTSPServer类用于构建一个RTSP服务器,该类同时在其内部定义了一个RTSPClientSession类,用于处理单独的客户会话。首先创建RTSP服务器(具体实现类是DynamicRTSPServer),在创建过程中,先建立Socket(ourSocket)在TCP的554端口进行监听,然后把连接处理函数句柄
(RTSPServer:: incomingConnectionHandler)和socket句柄传给任务调度器(taskScheduler)。
任务调度器把socket句柄放入后面select调用中用到的socket句柄集(fReadSet)中,同时将socket句柄和incomingConnectionHandler句柄关联起来。接着,主程序开始进入任务调度器的主循环(doEventLoop),在主循环中调用系统函数select阻塞,等待网络连接。当RTSP客户端输入(rtsp://192.168.1.109/1.mpg)连接服务器时,select返回对应的scoket,进而根据前面保存的对应关系,可找到对应处理函数句柄,这里就是前面提到的incomingConnectionHandler了。在incomingConnectionHandler中创建了RTSPClientSession,开始对这个客户端的会话进行处理。
具体分析如下:
DynamicRTSPServer::creatnew():1.调用继承自RTPSever::setUpOurSocket:1.调用GroupsockHelper 的setupStreamSocket创建一个socket连接,并绑定,2.设置socket的发送缓存大小,3.调用listen开始监听端口,设置同时最大能处理连接数LISTEN_BACKLOG_SIZE=20,如果达到这个上限则client端将收到ECONNERREFUSED的错误4.测试绑定端口是否为0,为0的话重新绑定断口,并返回系统自己选择的新的端口。5.返回建立的socket文件描述符
2.调用自己和RTPSever的构造函数:RTPSever构造函数:
1.用一个UsageEnvironment对象的引用构造其父类Medium
2.设置最大等待回收连接时间reclamationTestSeconds,超过这个时间从客户端没有RTSP命令或者RTSP的RR包则收回其RTSPClientSession
3.建立一个HashTable(实际上是一个BasicHashTable),fServerMediaSessions指向这个表。4.调用参数UsageEnvironment对象env的成员,一个TaskScheduler指针所指对象(实际就是一个BasicTaskScheduler对象)的成员函数turnOnBackgroundReadHandling():1.调用一个HandlerSet::assignHandler()创建一个Handler,把socketNum【此处为服务器监听的socket描述符】和处理函数RTSPServer::incomingConnectionHandler(),还有指向RTSPSever的指针绑定在一起。incomingConnectionHandler作用:1.调用accept返回服务器与客户端连接的socket描述符2.设置客户端描述符为非阻塞3.增加客户端socket描述符的发送缓存为50*1024
4.为此客户端随机分配一个sessionId
5.用客户端socket描述符clientSocket,sessionId,和客户端地址clientAddr调用creatNewClientSession创建一个clientSession。
2,请求消息处理过程上节我们谈到RTSP服务器收到客户端的连接请求,建立了RTSPClientSession类,处理单独的客户会话。在建立 RTSPClientSession的过程中,将新建立的socket句柄(clientSocket)和RTSP请求处理函数句柄RTSPClientSession::incomingRequestHandler传给任务调度器,由任务调度器对两者进行一对一关联。当客户端发出 RTSP请求后,服务器主循环中的select调用返回,根据socket句柄找到对应的incomingRequestHandler,开始消息处理。先进行消息的解析。
RTSPClientSessio