rtsp连接断开_EasyRTSPServer在rtp over udp客户端未发送teardown导致Server没有即时关闭流...

当在rtp over udp模式下,rtsp客户端未发送teardown就断开连接时,EasyRTSPServer会等待65秒才关闭流。通过在RTSPClientConnection中保存session值,并在断开连接时根据该值查找并删除相应ClientSession,可以即时关闭流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原标题:EasyRTSPServer在rtp over udp客户端未发送teardown导致Server没有即时关闭流

背景分析

RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP的作用相当于流媒体服务器的远程控制。服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而且允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,还可以支持多方视频会议(Video onference)。EasyRTSPServer应运而生。

关于EasyRTSPServer

EasyRTSPServer是一套稳定、高效、可靠、多平台支持的RTSP-Server组件, 接口调用非常简单成熟,无需关注RTSPServer中关于客户端监听接入、音视频多路复用、 RTSP具体流程、RTP打包与发送等相关问题,支持多种音视频格式, 再也不用去处理整个RTSP OPTIONS/DESCRIBE/SETUP/PLAY/RTP/RTCP的复杂流程和担心内存释放的问题了, 非常适合于安防领域、教育领域、互联网直播领域等。

EasyRTSPServer在rtp over udp客户端没有发送teardown关闭导致Server没有即时关闭流

提出问题

在rtp over udp模式下, rtsp客户端没有发送teardown而直接断开连接时需要等待65秒才回调关闭的问题

分析问题

在RTSPClientConnection中没有保存相应的session值, 所以在RTSPClientConnection断开时, 并没有删除相应的RTSPClientSession;

解决问题

在RTSPClientConnection的声明中,增加以下定义;

char fClientSessionIdStr[16]; //for rtp over udp

GenericMediaServer.hh 增加createNewClientSessionWithId的参数char *pSessionIdStr

ClientSession* createNewClientSessionWithId(UsageEnvironment *pEnv, char *pSessionIdStr);

GenericMediaServer::ClientSession* GenericMediaServer::createNewClientSessionWithId(UsageEnvironment *_pEnv, char *pSessionIdStr) {

u_int32_t sessionId;

char sessionIdStr[16] = {0};

// Choose a random (unused) 32-bit integer for the session id

// (it will be encoded as a 8-digit hex number). (We avoid choosing session id 0,

// because that has a special use by some servers.)

do {

sessionId = (u_int32_t)our_random32();

snprintf(sessionIdStr, sizeof sessionIdStr, "%08X", sessionId);

} while (sessionId == 0 || lookupClientSession(sessionIdStr) != NULL);

ClientSession* clientSession = createNewClientSession(sessionId, _pEnv);

if (clientSession != NULL) fClientSessions->Add(sessionIdStr, clientSession);

if (NULL != pSessionIdStr) strcpy(pSessionIdStr, sessionIdStr); //此处返回生成的sessionId, 后续要根据该值找到对应的ClientSession

return clientSession;

}

void RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead, UsageEnvironment *pEnv) {

//找到以下代码

if (authenticationOK("SETUP", urlTotalSuffix, (char const*)fRequestBuffer)) {

memset(fClientSessionIdStr, 0x00, sizeof(fClientSessionIdStr));

clientSession

= (RTSPServer::RTSPClientSession*)fOurRTSPServer.createNewClientSessionWithId(pEnv, fClientSessionIdStr); //此处记录ClientSession的sessionId

}

}

此时,在RTSPClientConnection中已经保存了对应的SessionId, 在客户端断开连接时, 可以根据该SessionId, 找到相应的ClientSession, 然后删除;

void RTSPServer::stopTCPStreamingOnSocket(UsageEnvironment *pEnv, int socketNum, int *clientTrackNum, char *clientSessionIdStr){

// Close any stream that is streaming over "socketNum" (using RTP/RTCP-over-TCP streaming):

RTSPClientSession *pClientSession = NULL;

LockClientConnection();

do

{

streamingOverTCPRecord* sotcp

= (streamingOverTCPRecord*)fTCPStreamingDatabase->Lookup((char const*)socketNum);

if (sotcp != NULL) { //rtp over tcp

do {

RTSPClientSession* clientSession

= (RTSPServer::RTSPClientSession*)lookupClientSession(sotcp->fSessionId);

if (clientSession != NULL) {

//clientSession->SetAssignSink(assignSink);

clientSession->deleteStreamByTrack(pEnv, sotcp->fTrackNum, False, clientTrackNum);

}

streamingOverTCPRecord* sotcpNext = sotcp->fNext;

sotcp->fNext = NULL;

delete sotcp;

sotcp = sotcpNext;

} while (sotcp != NULL);

fTCPStreamingDatabase->Remove((char const*)socketNum);

}

else if ( (clientTrackNum) && (*clientTrackNum==0)) //rtp over udp

{

pClientSession = (RTSPServer::RTSPClientSession*)lookupClientSession(clientSessionIdStr);

}

}while (0);

UnlockClientConnection();

if (pClientSession != NULL) //pClientSession不为空, 说明为rtp over udp

{

delete pClientSession;

}

}

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值