一、首先是本地监听的建立:StartServer() ->
-->QTSServer::Initialize()
--->QTSServer::CreateListeners() //函数中根据本地xml配置文件中的rtsp_port进行监听的建立
-->QTSServer::StartTasks() //开启Socket读取
具体函数在:
-
QTSServer::CreateListeners()
-
{
-
…
-
newListenerArray[curPortIndex] = NEW RTSPListenerSocket();
-
QTSS_Error err = newListenerArray[curPortIndex]->Initialize(thePortTrackers[count3].fIPAddr, thePortTrackers[count3].fPort);
-
-
…
-
}
-
void QTSServer::StartTasks()
-
{
-
fRTCPTask = new RTCPTask();
-
fStatsTask = new RTPStatsUpdaterTask();
-
-
-
-
for (UInt32 x = 0; x < fNumListeners; x++)
-
fListeners[x]->RequestEvent(EV_RE);
-
}
二、会话建立
先看RTSPListenerSocket类:
Socket的读取统一归于EventContext类中的EventThread线程,具体到EventThread::Entry()中的select_waitevent()捕获。
EventThread::Entry()函数中查找EventThread::fRefTable,获取对应的EventContext。得到的是EventContext类型的派生类RTSPListenerSocket。
-
…
-
EventContext* theContext = (EventContext*)ref->GetObject();
-
theContext->ProcessEvent(theCurrentEvent.er_eventbits);
-
…
调用RTSPListenerSocket的ProcessEvent()函数,进而调用TCPListenerSocket::ProcessEvent(),在TCPListenerSocket::ProcessEvent()中accept Socket
-
theTask = this->GetSessionTask(&theSocket);
-
if (theTask == NULL)
-
{
-
close(osSocket);
-
if (theSocket)
-
theSocket->fState &= ~kConnected;
-
}
-
else
-
{
-
Assert(osSocket != EventContext::kInvalidFileDesc);
-
-
-
-
int one = 1;
-
int err = ::setsockopt(osSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(int));
-
AssertV(err == 0, OSThread::GetErrno());
-
-
err = ::setsockopt(osSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&one, sizeof(int));
-
AssertV(err == 0, OSThread::GetErrno());
-
-
int sndBufSize = 96L * 1024L;
-
err = ::setsockopt(osSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sndBufSize, sizeof(int));
-
AssertV(err == 0, OSThread::GetErrno());
-
-
-
-
theSocket->Set(osSocket, &addr);
-
theSocket->InitNonBlocking(osSocket);
-
theSocket->SetTask(theTask);
-
theSocket->RequestEvent(EV_RE);
-
}
将(TCPSocket*)theSocket加入到侦听队列中,从上以后就开始对该条已建立accept的(TCPSocket*)theSocket描述请求由此处所创建的(RTSPSession*)theTask进行处理。
三、RTSP交互
同样Socket的读取统一归于EventContext类中的EventThread线程,具体到EventThread::Entry()中的select_waitevent()捕获。
EventThread::Entry()函数中查找EventThread::fRefTable,获取对应的EventContext。此时查找到第二部分中加入到侦听队列的Socket,进入
到EventContext中的ProcessEvent()函数:
-
virtual void ProcessEvent(int )
-
{
-
if (EVENTCONTEXT_DEBUG)
-
{
-
if (fTask== NULL)
-
qtss_printf("EventContext::ProcessEvent context=%lu task=NULL\n",(UInt32) this);
-
else
-
qtss_printf("EventContext::ProcessEvent context=%lu task=%lu TaskName=%s\n",(UInt32)this,(UInt32) fTask, fTask->fTaskName);
-
}
-
-
if (fTask != NULL)
-
fTask->Signal(Task::kReadEvent);
-
}
激活第二部分中theSocket所映射的theTask,进行Socket读取。此处fTask就是RTSPSession类。把RTSPSession加入到TaskThread的队列等待RTSPSession::Run()被调用,
进而就是RTSPSession::Run()对具体的RTSP请求进行的处理。
好了,今天就简单推进到此处,下一部分将深入到RTSPSession中具体对报文如何解析,以及RTSPSession如何与其他模块&Task进行交互进行分析!
(责任编辑:IT) |