上一篇Live555源码解析(2) - RTSP协议概述对RTSP进行了整体介绍,对会话交互过程及通常应用场景做了示例。接下来,我们就从媒体服务器的本职工作服务开始谈起。
1. 从服务器说起
要服务,就必须有服务器,有开放给外界客户端访问的地址和端口。先放源码:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
UserAuthenticationDatabase* authDB = NULL;
portNumBits rtspServerPortNum = 554;
//@1 建立RTSP服务器
RTSPServer* rtspServer = DynamicRTSPServer::createNew(*env, rtspServerPortNum, authDB);
if(rtspServer == NULL)
{
rtspServerPortNum = 8554;
rtspServer = DynamicRTSPServer::createNew(*env, rtspServerPortNum, authDB);
}
if(rtspServer == NULL)
{
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
源码分析:
@1 建立RTSP服务器
createNew()函数有三个参数,分别说明如下:- *env
env对应的UsageEnvironment、BasicUsageEnvironment主要为后台运行机制,提供基础支持。具体已在本系列Live555源码解析(1) - Main 寻根问祖,留其筋骨中详细说明,这里不再赘述。 - rtspServerPortNum
RTSP默认知名端口为554,如被占用,则使用8554。如仍不能成功创建,则提示错误后退出程序。 - authDB
authDB对应UserAuthenticationDatabase,默认情况下不会定义ACCESS_CONTROL,即关闭认证机制。因此此处不进行分析,后续如有需求,可专门整理下互联网认证机制概况。
本句代码中出现了两个class,分别为RTSPServer、DynamicRTSPServer。第一眼看应该是继承关系,确实也是继承关系,只不过希望先留个更清晰的印象。
- *env
2. DynamicRTSPServer::createNew()
源码:
DynamicRTSPServer* DynamicRTSPServer::createNew(UsageEnvironment& env, Port ourPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds)
{
//@1 创建Socket
int ourSocket = setUpOurSocket(env, ourPort);
if (ourSocket == -1) return NULL;
//@2 DynamicRTSPServer构造函数
return new DynamicRTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds);
}
源码分析:
@1 创建Socket
由于RTSPServer、RTSPServerSupportingHTTPStreaming、DynamicRTSPServer均为实现setUpOurSocket()函数,因此这里实际调用的是父类GenericMediaServer中的setUpOurSocket()。int GenericMediaServer::setUpOurSocket(UsageEnvironment& env, Port& ourPort) { int ourSocket = -1; do { //如果当前Socket已被本地服务器占用,则不允许重复使用 NoReuse dummy(env); //@1.1 创建TCPSocket ourSocket = setupStreamSocket(env, ourPort); if(ourSocket < 0) break; //@1.2 调整Socket发送Buffer大小 if(!increaseSendBufferTo(env, ourSocket, 50*1024)) break; //@1.3 切换Socket模式为LISTEN if(listen(ourSocket, LISTEN_BACKLOG_SIZE) < 0) { env.s