Live555 RTSP服务器不使用UDP
Live555 RTSP server does not use UDP
我有一个非常基本的 live555 RTSP 服务器和客户端,用于传输用 c++ 编写的 h264 流。
这是我为客户端准备的代码(改编自 testProgs/testRTSPClient.cpp,与 live555 捆绑在一起)
client->scheduler = BasicTaskScheduler::createNew();
client->env = BasicUsageEnvironment::createNew(*client->scheduler);
client->rtspClient = NULL;
RTSP_CLIENT::eventLoopWatchVariable = 0;
openURL(client, *client->env, string(string("rtsp://") + ip_address + ":" + to_string(BASE_RTSP_PORT + iris_id) + "/iris").c_str());
client->env->taskScheduler().doEventLoop(&RTSP_CLIENT::eventLoopWatchVariable);
void openURL(RTSP_CLIENT* client, UsageEnvironment& env, char const* rtspURL) {
// Begin by creating a "RTSPClient" object. Note that there is a separate "RTSPClient" object for each stream that we wish
// to receive (even if more than stream uses the same "rtsp://" URL).
while (!client->rtspClient) {
client->rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, "main");
}
// Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream.
// Note that this command - like all RTSP commands - is sent asynchronously; we do not block, waiting for a response.
// Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop:
client->rtspClient->sendDescribeCommand(continueAfterDESCRIBE);
}
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) {
do {
UsageEnvironment& env = rtspClient->envir(); // alias
StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
if (resultCode != 0) {
env << *rtspClient << "Failed to get a SDP description: " << resultString << "\n";
delete[] resultString;
break;
}
char* const sdpDescription = resultString;
env << *rtspClient << "Got a SDP description:\n" << sdpDescription << "\n";
// Create a media session object from this SDP description:
scs.session = MediaSession::createNew(env, sdpDescription);
delete[] sdpDescription; // because we don't need it anymore
if (scs.session == NULL) {
env << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg() << "\n";
break;
} else if (!scs.session->hasSubsessions()) {
env << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)\n";
break;
}
// Then, create and set up our data source objects for the session. We do this by iterating over the session's 'subsessions',
// calling "MediaSubsession::initiate()", and then sending a RTSP "SETUP" command, on each one.
// (Each 'subsession' will have its own data source.)
scs.iter = new MediaSubsessionIterator(*scs.session);
setupNextSubsession(rtspClient);
return;
} while (0);
// An unrecoverable error occurred with this stream.
shutdownStream(rtspClient);
}
这是我为服务器准备的代码(改编自 testProgs/testOnDemandRTSPServer.cpp,与 live555 捆绑在一起)
rtsp_server->taskSchedular = BasicTaskScheduler::createNew();
rtsp_server->usageEnvironment = BasicUsageEnvironment::createNew(*rtsp_server->taskSchedular);
rtsp_server->rtspServer = RTSPServer::createNew(*rtsp_server->usageEnvironment, BASE_RTSP_PORT + iris_id, NULL);
rtsp_server->eventLoopWatchVariable = 0;
if(rtsp_server->rtspServer == NULL) {
*rtsp_server->usageEnvironment << "Failed to create rtsp server ::" << rtsp_server->usageEnvironment->getResultMsg() <<"\n";
return false;
}
rtsp_server->sms = ServerMediaSession::createNew(*rtsp_server->usageEnvironment, "iris", "iris", "stream");
rtsp_server->liveSubSession = H264LiveServerMediaSession::createNew(*rtsp_server->usageEnvironment, true);
rtsp_server->sms->addSubsession(rtsp_server->liveSubSession);
rtsp_server->rtspServer->addServerMediaSession(rtsp_server->sms);
rtsp_server->taskSchedular->doEventLoop(&rtsp_server->eventLoopWatchVariable);
我假设 live555 默认使用 UDP 将数据从服务器传输到客户端,这正是我想要的,因为它比 TCP 具有延迟优势。然而,当 运行 服务器客户端时,我碰巧检查了 netstat,我发现了这个:
~# netstat | grep 8554
tcp 0 0 x.x.x.x:8554 wsip-x-x-x-x:39224 ESTABLISHED
然而,它表明通信是通过 TCP 而不是 UDP。我在这里有点困惑,我在这里误解了 netstat 吗?
我是否需要调整我的 C++ 代码以强制通过 UDP 而不是 TCP 进行通信?
好的,我找到答案了。为了帮助其他对此感到好奇的人,代码实际上都是正确的。也没有对 netstat 的错误解释。 RTSP 确实 运行 通过 TCP 而不是 UDP。但是,A/V 数据 运行 在 RTP 上的传输方法是 RTSP 简单协商和实例化的连接。 RTP 几乎总是 运行 而不是 UDP。要弄清楚 A/V 数据流经过的端口和协议,您需要嗅探通过 RTSP 发送的数据包。在我的例子中,A/V 数据流确实仍在通过 UDP。
我有一个非常基本的 live555 RTSP 服务器和客户端,用于传输用 c++ 编写的 h264 流。
这是我为客户端准备的代码(改编自 testProgs/testRTSPClient.cpp,与 live555 捆绑在一起)
client->scheduler = BasicTaskScheduler::createNew();
client->env = BasicUsageEnvironment::createNew(*client->scheduler);
client->rtspClient = NULL;
RTSP_CLIENT::eventLoopWatchVariable = 0;
openURL(client, *client->env, string(string("rtsp://") + ip_address + ":" + to_string(BASE_RTSP_PORT + iris_id) + "/iris").c_str());
client->env->taskScheduler().doEventLoop(&RTSP_CLIENT::eventLoopWatchVariable);
void openURL(RTSP_CLIENT* client, UsageEnvironment& env, char const* rtspURL) {
// Begin by creating a "RTSPClient" object. Note that there is a separate "RTSPClient" object for each stream that we wish
// to receive (even if more than stream uses the same "rtsp://" URL).
while (!client->rtspClient) {
client->rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, "main");
}
// Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream.
// Note that this command - like all RTSP commands - is sent asynchronously; we do not block, waiting for a response.
// Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop:
client->rtspClient->sendDescribeCommand(continueAfterDESCRIBE);
}
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) {
do {
UsageEnvironment& env = rtspClient->envir(); // alias
StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
if (resultCode != 0) {
env << *rtspClient << "Failed to get a SDP description: " << resultString << "\n";
delete[] resultString;
break;
}
char* const sdpDescription = resultString;
env << *rtspClient << "Got a SDP description:\n" << sdpDescription << "\n";
// Create a media session object from this SDP description:
scs.session = MediaSession::createNew(env, sdpDescription);
delete[] sdpDescription; // because we don't need it anymore
if (scs.session == NULL) {
env << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg() << "\n";
break;
} else if (!scs.session->hasSubsessions()) {
env << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)\n";
break;
}
// Then, create and set up our data source objects for the session. We do this by iterating over the session's 'subsessions',
// calling "MediaSubsession::initiate()", and then sending a RTSP "SETUP" command, on each one.
// (Each 'subsession' will have its own data source.)
scs.iter = new MediaSubsessionIterator(*scs.session);
setupNextSubsession(rtspClient);
return;
} while (0);
// An unrecoverable error occurred with this stream.
shutdownStream(rtspClient);
}
这是我为服务器准备的代码(改编自 testProgs/testOnDemandRTSPServer.cpp,与 live555 捆绑在一起)
rtsp_server->taskSchedular = BasicTaskScheduler::createNew();
rtsp_server->usageEnvironment = BasicUsageEnvironment::createNew(*rtsp_server->taskSchedular);
rtsp_server->rtspServer = RTSPServer::createNew(*rtsp_server->usageEnvironment, BASE_RTSP_PORT + iris_id, NULL);
rtsp_server->eventLoopWatchVariable = 0;
if(rtsp_server->rtspServer == NULL) {
*rtsp_server->usageEnvironment << "Failed to create rtsp server ::" << rtsp_server->usageEnvironment->getResultMsg() <<"\n";
return false;
}
rtsp_server->sms = ServerMediaSession::createNew(*rtsp_server->usageEnvironment, "iris", "iris", "stream");
rtsp_server->liveSubSession = H264LiveServerMediaSession::createNew(*rtsp_server->usageEnvironment, true);
rtsp_server->sms->addSubsession(rtsp_server->liveSubSession);
rtsp_server->rtspServer->addServerMediaSession(rtsp_server->sms);
rtsp_server->taskSchedular->doEventLoop(&rtsp_server->eventLoopWatchVariable);
我假设 live555 默认使用 UDP 将数据从服务器传输到客户端,这正是我想要的,因为它比 TCP 具有延迟优势。然而,当 运行 服务器客户端时,我碰巧检查了 netstat,我发现了这个:
~# netstat | grep 8554
tcp 0 0 x.x.x.x:8554 wsip-x-x-x-x:39224 ESTABLISHED
然而,它表明通信是通过 TCP 而不是 UDP。我在这里有点困惑,我在这里误解了 netstat 吗?
我是否需要调整我的 C++ 代码以强制通过 UDP 而不是 TCP 进行通信?
好的,我找到答案了。为了帮助其他对此感到好奇的人,代码实际上都是正确的。也没有对 netstat 的错误解释。 RTSP 确实 运行 通过 TCP 而不是 UDP。但是,A/V 数据 运行 在 RTP 上的传输方法是 RTSP 简单协商和实例化的连接。 RTP 几乎总是 运行 而不是 UDP。要弄清楚 A/V 数据流经过的端口和协议,您需要嗅探通过 RTSP 发送的数据包。在我的例子中,A/V 数据流确实仍在通过 UDP。