从零开始学习EasyDarwin(RTSP连接监听初始化)

来源:互联网 发布:次声波软件 编辑:程序博客网 时间:2024/05/26 02:19

注:对RTSP协议有了大致了解后,开始一行行跟代码RTSP相关代码,偶尔发现csdn上longlong530的这篇文章讲的知识有条有理就推荐给大伙一起学习和研究。

网上有很多大侠已经对Darwin做了详细的剖析,在下仅本着积累经验的目的,将Darwin的学习过程记录下来,同时与网友们交流学习,今天先来分析下Darwin如果根据配置文件监听RTSP连接的流程。

RTSP相关的代码主要是在QTSServer.cpp QTSServer.h文件中

RTSP建立侦听调用堆栈层次如下(函数参数默认省略,具体以代码为准):

–> 1. RunServer.cpp:StartServer() 
–> 2. QTSServer::Initialize() 
–> 3. QTSServer::CreateListeners()//函数根据本地xml配置文件中的rtsp_port和bind_ip_addr字段进行监听的建立. 
UInt32* theIPAddrs = this->GetRTSPIPAddrs(inPrefs, &theNumAddrs); 
UInt16* thePorts = GetRTSPPorts(inPrefs, &theNumPorts);

–> 4. 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;//ip地址        是否需要创建RTSPListenerSocket,默认创建        Bool16 fNeedsCreating;    };    PortTracking* theRTSPPortTrackers = NULL;       UInt32 theTotalRTSPPortTrackers = 0;    PortTracking* theHTTPPortTrackers = NULL;       UInt32 theTotalHTTPPortTrackers = 0;    // Get the IP addresses from the pref    //从配置文件中获取ip和端口    UInt32 theNumAddrs = 0;    UInt32* theIPAddrs = this->GetRTSPIPAddrs(inPrefs, &theNumAddrs);       UInt32 index = 0;    // Stat Total Num of RTSP Port    if ( inPortOverride != 0)    {        //yige        theTotalRTSPPortTrackers = theNumAddrs; // one port tracking struct for each IP addr        theRTSPPortTrackers = NEW PortTracking[theTotalRTSPPortTrackers];        for (index = 0; index < theNumAddrs; index++)        {            theRTSPPortTrackers[index].fPort = inPortOverride;            theRTSPPortTrackers[index].fIPAddr = theIPAddrs[index];        }    }    else    {        UInt32 theNumPorts = 0;        UInt16* thePorts = GetRTSPPorts(inPrefs, &theNumPorts);        theTotalRTSPPortTrackers = theNumAddrs * theNumPorts;        theRTSPPortTrackers = NEW PortTracking[theTotalRTSPPortTrackers];        UInt32 currentIndex  = 0;        for (index = 0; index < theNumAddrs; index++)        {            for (UInt32 portIndex = 0; portIndex < theNumPorts; portIndex++)            {                currentIndex = (theNumPorts * index) + portIndex;                theRTSPPortTrackers[currentIndex].fPort = thePorts[portIndex];                theRTSPPortTrackers[currentIndex].fIPAddr = theIPAddrs[index];            }        }        delete [] thePorts;    }    // Stat Total Num of HTTP Port    {        theTotalHTTPPortTrackers = theNumAddrs;        theHTTPPortTrackers = NEW PortTracking[theTotalHTTPPortTrackers];        UInt16 theHTTPPort = inPrefs->GetHTTPServicePort();        UInt32 currentIndex  = 0;        for (index = 0; index < theNumAddrs; index++)        {            theHTTPPortTrackers[index].fPort = theHTTPPort;            theHTTPPortTrackers[index].fIPAddr = theIPAddrs[index];        }    }        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*[theTotalRTSPPortTrackers + theTotalHTTPPortTrackers];    UInt32 curPortIndex = 0;    // RTSPPortTrackers check    for (UInt32 count = 0; count < theTotalRTSPPortTrackers; count++)    {        for (UInt32 count2 = 0; count2 < fNumListeners; count2++)        {            if ((fListeners[count2]->GetLocalPort() == theRTSPPortTrackers[count].fPort) &&                (fListeners[count2]->GetLocalAddr() == theRTSPPortTrackers[count].fIPAddr))            {                theRTSPPortTrackers[count].fNeedsCreating = false;                newListenerArray[curPortIndex++] = fListeners[count2];                Assert(curPortIndex <= theTotalRTSPPortTrackers);                break;            }        }    }    // HTTPPortTrackers check    for (UInt32 count = 0; count < theTotalHTTPPortTrackers; count++)    {        for (UInt32 count2 = 0; count2 < fNumListeners; count2++)        {            if ((fListeners[count2]->GetLocalPort() == theHTTPPortTrackers[count].fPort) &&                (fListeners[count2]->GetLocalAddr() == theHTTPPortTrackers[count].fIPAddr))            {                theHTTPPortTrackers[count].fNeedsCreating = false;                newListenerArray[curPortIndex++] = fListeners[count2];                Assert(curPortIndex <= theTotalRTSPPortTrackers+theTotalHTTPPortTrackers);                break;            }        }    }    // Create any new <RTSP> listeners we need    for (UInt32 count3 = 0; count3 < theTotalRTSPPortTrackers; count3++)    {        if (theRTSPPortTrackers[count3].fNeedsCreating)        {        //// 监听创建RTSP侦听            newListenerArray[curPortIndex] = NEW RTSPListenerSocket();            QTSS_Error err = newListenerArray[curPortIndex]->Initialize(theRTSPPortTrackers[count3].fIPAddr, theRTSPPortTrackers[count3].fPort);            char thePortStr[20];            qtss_sprintf(thePortStr, "%hu", theRTSPPortTrackers[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            {                //                // This listener was successfully created.                if (startListeningNow)                    newListenerArray[curPortIndex]->RequestEvent(EV_RE);                curPortIndex++;            }        }    }    // Create any new <HTTP> listeners we need    for (UInt32 count3 = 0; count3 < theTotalHTTPPortTrackers; count3++)    {        if (theHTTPPortTrackers[count3].fNeedsCreating)        {            newListenerArray[curPortIndex] = NEW HTTPListenerSocket();            QTSS_Error err = newListenerArray[curPortIndex]->Initialize(theHTTPPortTrackers[count3].fIPAddr, theHTTPPortTrackers[count3].fPort);            char thePortStr[20];            qtss_sprintf(thePortStr, "%hu", theHTTPPortTrackers[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            {                //                // This listener was successfully created.                if (startListeningNow)                    newListenerArray[curPortIndex]->RequestEvent(EV_RE);                curPortIndex++;            }        }    }    //    // Kill any listeners that we no longer need    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 = newListenerArray;    fNumListeners = curPortIndex;    UInt32 portIndex = 0;    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 [] theRTSPPortTrackers;    delete [] theHTTPPortTrackers;    return (fNumListeners > 0);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219

从配置文件中获取RTSP监听地址列表,即0配置项,系统默认是为0,该配置项在多网卡的服务器上可能需要用到,一般我们调试学习的时候可以不考虑。但是还是介绍下,也比较简单。

获取端口函数: 
QTSServer::GetRTSPPorts(QTSServerPrefs* inPrefs, UInt32* outNumPortsPtr)

获取网络地址函数: 
QTSServer::GetRTSPIPAddrs(QTSServerPrefs* inPrefs, UInt32* outNumAddrsPtr)

如此根据配置文件的IP、port,即已将对应的Socket建立完成,且startListeningNow默认是false,需要在Runserver中调用sServer->StartTasks();方能开始监听

void QTSServer::StartTasks(){    fRTCPTask = new RTCPTask();    fStatsTask = new RTPStatsUpdaterTask();    //    // Start listening    for (UInt32 x = 0; x < fNumListeners; x++)        fListeners[x]->RequestEvent(EV_RE);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下一小节,分析RequestEvent内部的处理流程。谢谢大家阅读,感谢大家

0 0
原创粉丝点击