【转载请注明出处】:http://blog.csdn.net/longlong530
网上有很多大侠已经对Darwin做了详细的剖析,在下仅本着积累经验的目的,将Darwin的学习过程记录下来,同时与网友们交流学习,今天先来分析下Darwin如果根据配置文件监听RTSP连接的流程。
1. Darwin系统初始化,Bool16 QTSServer::Initialize(.....)
2. QTSServer::CreateListeners(...)根据本地xml配置文件中的地址和端口进行监听的建立,主要有两个配置项:
3. void QTSServer::StartTasks() 开始监听上一步建立起来的Socket 列表
Bool16 QTSServer::CreateListeners(Bool16 startListeningNow, QTSServerPrefs* inPrefs, UInt16 inPortOverride)
{
struct PortTracking
{
PortTracking() : fPort(0), fIPAddr(0), fNeedsCreating(true) {}
UInt16 fPort; //端口号
UInt32 fIPAddr;//地址
Bool16 fNeedsCreating;//是否需要创建RTSPListenerSocket,默认创建
};
PortTracking* thePortTrackers = NULL;
UInt32 theTotalPortTrackers = 0;
// Get the IP addresses from the pref 获取配置文件中用于监听RTSP连接的IP地址和端口号
UInt32 theNumAddrs = 0;
UInt32* theIPAddrs = this->GetRTSPIPAddrs(inPrefs, &theNumAddrs);
UInt32 index = 0;
//inPortOverride该参数为命令行参数传入,默认为0. -p XXX: Specify the default RTSP listening port of the server
if ( inPortOverride != 0)
{
theTotalPortTrackers = theNumAddrs; // one port tracking struct for each IP addr
thePortTrackers = NEW PortTracking[theTotalPortTrackers];
for (index = 0; index < theNumAddrs; index++)
{
thePortTrackers[index].fPort = inPortOverride;
thePortTrackers[index].fIPAddr = theIPAddrs[index];
}
}
else
{
UInt32 theNumPorts = 0;
UInt16* thePorts = GetRTSPPorts(inPrefs, &theNumPorts); //根据xml配置文件中的获取端口号
theTotalPortTrackers = theNumAddrs * theNumPorts;
thePortTrackers = NEW PortTracking[theTotalPortTrackers];//一共需要监听的数量为:端口数 * IP地址数
UInt32 currentIndex = 0;
for (index = 0; index < theNumAddrs; index++)
{
for (UInt32 portIndex = 0; portIndex < theNumPorts; portIndex++)
{
currentIndex = (theNumPorts * index) + portIndex;
thePortTrackers[currentIndex].fPort = thePorts[portIndex];
thePortTrackers[currentIndex].fIPAddr = theIPAddrs[index];
}
}
delete [] thePorts;
}
delete [] theIPAddrs;
//
// Now figure out which of these ports we are *already* listening on.
// If we already are listening on that port, just move the pointer to the
// listener over to the new array
TCPListenerSocket** newListenerArray = NEW TCPListenerSocket*[theTotalPortTrackers];
UInt32 curPortIndex = 0;
for (UInt32 count = 0; count < theTotalPortTrackers; count++)
{
for (UInt32 count2 = 0; count2 < fNumListeners; count2++)
{
if ((fListeners[count2]->GetLocalPort() == thePortTrackers[count].fPort) &&
(fListeners[count2]->GetLocalAddr() == thePortTrackers[count].fIPAddr))
{
//如果fListeners监听列表中已经对该ip+port进行了监听,那么就不再监听;
thePortTrackers[count].fNeedsCreating = false;
newListenerArray[curPortIndex++] = fListeners[count2];
Assert(curPortIndex <= theTotalPortTrackers);
break;
}
}
}
//
// 创建为需要监听的IP+PORT创建RTSPListenerSocket
for (UInt32 count3 = 0; count3 < theTotalPortTrackers; count3++)
{
if (thePortTrackers[count3].fNeedsCreating) //不需要监听的已经在上一步把该字段置为false了.
{
//创建RTSP监听任务;
newListenerArray[curPortIndex] = NEW RTSPListenerSocket();
QTSS_Error err = newListenerArray[curPortIndex]->Initialize(thePortTrackers[count3].fIPAddr, thePortTrackers[count3].fPort);
char thePortStr[20];
qtss_sprintf(thePortStr, "%hu", thePortTrackers[count3].fPort);
//
// If there was an error creating this listener, destroy it and log an error
if ((startListeningNow) && (err != QTSS_NoErr))
delete newListenerArray[curPortIndex];
if (err == EADDRINUSE)
{
QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssListenPortInUse, 0, thePortStr);
}
else if (err == EACCES)
{
QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssListenPortAccessDenied, 0, thePortStr);
}
else if (err != QTSS_NoErr)
{
QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssListenPortError, 0, thePortStr);
}
else
{
//将第一个可用端口赋值给fOKPort,保存,后续通过GetOKPort()对外提供RTSP监听端口即为此端口;
if(fOKPort == 0)
{
fOKPort = thePortTrackers[count3].fPort;
}
//
// This listener was successfully created.如果需要监听,则立即开始监听该socket上面的连接.
if (startListeningNow)
newListenerArray[curPortIndex]->RequestEvent(EV_RE);
curPortIndex++;
}
}
}
//
//将fListeners监听列表中未在配置文件监听范围内的socket杀掉~
for (UInt32 count4 = 0; count4 < fNumListeners; count4++)
{
Bool16 deleteThisOne = true;
for (UInt32 count5 = 0; count5 < curPortIndex; count5++)
{
if (newListenerArray[count5] == fListeners[count4])
deleteThisOne = false;
}
if (deleteThisOne)
fListeners[count4]->Signal(Task::kKillEvent);
}
//
// Finally, make our server attributes and fListener privy to the new...最后将监听列表赋给fListeners,监听数量赋给fNumListeners
fListeners = newListenerArray;
fNumListeners = curPortIndex;
UInt32 portIndex = 0;
//将监听的端口号列表保存起来,key值为qtssSvrRTSPPorts
for (UInt32 count6 = 0; count6 < fNumListeners; count6++)
{
if (fListeners[count6]->GetLocalAddr() != INADDR_LOOPBACK)
{
UInt16 thePort = fListeners[count6]->GetLocalPort();
(void)this->SetValue(qtssSvrRTSPPorts, portIndex, &thePort, sizeof(thePort), QTSSDictionary::kDontObeyReadOnly);
portIndex++;
}
}
//设置端口列表的个数;
this->SetNumValues(qtssSvrRTSPPorts, portIndex);
delete [] thePortTrackers;
return (fNumListeners > 0);
}
UInt32* QTSServer::GetRTSPIPAddrs(QTSServerPrefs* inPrefs, UInt32* outNumAddrsPtr)
{
UInt32 numAddrs = inPrefs->GetNumValues(qtssPrefsRTSPIPAddr);//获取配置文件中rtsp监听地址的数量;
UInt32* theIPAddrArray = NULL;
if (numAddrs == 0)//如果配置的监听地址数量为0,则设置为INADDR_ANY
{
*outNumAddrsPtr = 1;
theIPAddrArray = NEW UInt32[1];
theIPAddrArray[0] = INADDR_ANY;//INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
}
else
{
theIPAddrArray = NEW UInt32[numAddrs + 1];
UInt32 arrIndex = 0;
for (UInt32 theIndex = 0; theIndex < numAddrs; theIndex++)
{
// Get the ip addr out of the prefs dictionary
QTSS_Error theErr = QTSS_NoErr;
char* theIPAddrStr = NULL;
theErr = inPrefs->GetValueAsString(qtssPrefsRTSPIPAddr, theIndex, &theIPAddrStr);
if (theErr != QTSS_NoErr)
{
delete [] theIPAddrStr;
break;
}
UInt32 theIPAddr = 0;
if (theIPAddrStr != NULL)
{
//IP地址从字符串转换成整型,并从网络字节顺序转换为主机字节顺序
theIPAddr = SocketUtils::ConvertStringToAddr(theIPAddrStr);
delete [] theIPAddrStr;
if (theIPAddr != 0)
theIPAddrArray[arrIndex++] = theIPAddr;
}
}
if ((numAddrs == 1) && (arrIndex == 0)) //如果配置文件的IP地址数量为1,但是解析不到,则同样按照INADDR_ANY方式监听
theIPAddrArray[arrIndex++] = INADDR_ANY;
else
theIPAddrArray[arrIndex++] = INADDR_LOOPBACK; //INADDR_LOOPBACK, 也就是绑定地址LOOPBAC, 往往是127.0.0.1, 只能收到127.0.0.1上面的连接请求
*outNumAddrsPtr = arrIndex;
}
return theIPAddrArray;
}
UInt16* QTSServer::GetRTSPPorts(QTSServerPrefs* inPrefs, UInt32* outNumPortsPtr)
{
*outNumPortsPtr = inPrefs->GetNumValues(qtssPrefsRTSPPorts); //获取qtssPrefsRTSPPorts对应的数组长度;
if (*outNumPortsPtr == 0)
return NULL;
UInt16* thePortArray = NEW UInt16[*outNumPortsPtr];
//获取监听端口号列表;
for (UInt32 theIndex = 0; theIndex < *outNumPortsPtr; theIndex++)
{
// Get the ip addr out of the prefs dictionary
UInt32 theLen = sizeof(UInt16);
QTSS_Error theErr = QTSS_NoErr;
theErr = inPrefs->GetValue(qtssPrefsRTSPPorts, theIndex, &thePortArray[theIndex], &theLen);
Assert(theErr == QTSS_NoErr);
}
return thePortArray;
}
void QTSServer::StartTasks()
{
fRTCPTask = new RTCPTask();
fStatsTask = new RTPStatsUpdaterTask();
//
// Start listening
for (UInt32 x = 0; x < fNumListeners; x++)
fListeners[x]->RequestEvent(EV_RE);
}
【转载请注明出处】:http://blog.csdn.net/longlong530