(转)live555 RTSP Server RTP over TCP BUG
最近碰到一个非常棘手的问题,NVR通过ONVIF协议接入IPC进行录像,在录像时,会发现其中有个别IPC会出现录像断断续续的情况。这种情况很难复现,但是这种情况一旦出现,整个过程会一直持续很长时间,一般是直到重启RTSP Server。
通过苦逼型的大规模测试发现:
1、IPC与NVR之间是通过RTP over TCP的方式传输数据(这个测试结果很简单就可以知道);
2、开启1个客户端(通过RTP over TCP传输数据),打开rtsp流后,使用任务管理器强制结束。紧接着马上再开1个客户端,打开rtsp流,稍等一会儿(1分钟左右),后面开启的这个流居然自动断开了。这是一个必现的bug。(这里测试时,客户端可使用VLC,不过VLC默认情况下是使用RTP over UDP的方式传输数据。要使用 over TCP方式接收数据,需要通过以下设置: “工具”->“首选项”,打开首选项对话框后,“显示设置”处点击“全部”单选按钮,在左侧树形菜单依次展开:“输入/编解码器”->“去复用器”->“RTP/RTSP”,选中“使用RTP over RTSP(TCP)”);
通过调试发现:
1、RTSPServer::createNew()的参数里面有个reclamationTestSeconds参数,该参数默认值为65;
2、RTSPServer::createNewClientSession创建一个RTSPClientSession实例时,RTSPClientSession构造函数会调用noteLiveness,noteLiveness会设置一个延时任务,该任务的延时时间即为1中的reclamationTestSeconds(其值为秒,需要转换为微秒,回调为livenessTimeoutTask)。noteLiveness除了在构造的时候调用,在RTSP SERVER接收到一个RR数据包后,也会调用(RR其实也用作了一种心跳包了);
3、RTSPServer::incomingConnectionHandler()函数在异常结束上一个客户端后,再打开一个客户端打开rtsp流时,函数中accept返回的socket的值和上一个客户端的socket句柄值是相同的(概率在50%以上,如果这里返回的socket句柄不同,这个bug就不会复现了);
通过以上3条,如果你读过live555的代码,应该知道是怎么回事了。上面2中设置的延时任务的回调函数livenessTimeoutTask,只干了一件事件,就是delete掉RTSPServer::createNewClientSession创建的实例。查看RTSPClientSession的析构函数,发现其居然把RTPInterface::fTCPStreams链表中对应的节点给删掉了。而RTP和RTCP包是通过RTSPServer::sendPacket发送到各个客户端的,在发送的时候,就是直接对RTPInterface::fTCPStreams保存的地址(即socket句柄)进行发送。如果RTPInterface::fTCPStreams中的socket清除了,客户端自然不会再接收到数据,出现断线已经是必然了。至此,断线的原因终于明了:即异常结束掉一个客户端,在65秒内(默认值为65),再开启一个客户端打开流,第二次打开的这条流会在65秒内必然断开,如果客户端有断线自动重连的功能,那么,断断续续的情况就出现了。
通过测试还发现,通过RTP over UDP的方式接收数据时,异常结束客户端,RTSP Server居然会接收到一条TEARDOWN消息,而在TEARDOWN消息的处理过程中,会清理掉client session和RTSP链接,即使用RTP OVER UDP的方式传输数据时,异常结束客户端,并不会出现上述bug,这个让我困惑不少,如果哪位知道,请告诉我原因。
其实解决这个问题,只需要注释掉livenessTimeoutTask中的delete语句就行了,不过这不是最终解决方案,因为会造成内存泄漏,最好的方式是使用SESSION ID和目标地址进行关联,在调用StreamState::endPlaying删除目的地址时,如果SESSION ID不对应,不从链表中清除掉对应的节点就行了。
转自:http://m.blog.csdn.net/blog/zxwangyun/40541023
(转)live555 RTSP Server RTP over TCP BUG的更多相关文章
- 【视频开发】RTSP SERVER(基于live555)详细设计
/* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...
- Live555研究之三 RTSP Server处理请求
RTSP Server会不断用select查询是否有socket连接,如果有则在(*handler->handlerProc)(handler->clientData, resultCon ...
- 一个RTSP/RTP over TCP 的丢包引起的问题
背景知识:可以查看https://www.cnblogs.com/lidabo/p/4483497.html RTSP/RTP over TCP TCP承载RTSP/RTP When you us ...
- RTSP - RTP over TCP
RTP over RTSP(TCP)(一) RTP over RTSP包混合发送的解决办法 RTSP - RTP over TCP To use TCP communication, ...
- 使用live555 在linux下搭建 rtsp server
系统环境 Debian 7 x64 / centos 7 x64 都可以 首先去下载源码 http://www.live555.com/liveMedia/public/live555-lates ...
- RTSP HTTP RTP RTCP
RTSP简介 RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议.RTSP对流 ...
- Managed Media Aggregation using Rtsp and Rtp
his article was written almost 2 years ago, it's content may not reflect the latest state of the cod ...
- live555 RTSP推送到Darwin出现404错误的解决
我们将Darwin部署到公网,接收live555 RTSP/RTP推送的时候,经常会出现在SETUP步骤Darwin返回404错误,经过查找原因,主要是Darwin对live555推送的sdp信息中的 ...
- 让EasyDarwin只支持RTP over TCP传输
我们经常需要EasyDarwin服务器支持公网流媒体传输,但很多时候,播放器默认都是通过RTP over UDP的形式在RTSP SETUP中请求,往往都以在内网接收不到UDP数据失败结束,那么我们如 ...
随机推荐
- 【Web】Tomcat中利用Session识别用户的基本原理
HTTP无状态的特性与Session.Cookie的存在 HTTP有一个特性:无状态的,就是前后两个HTTP事务它们并不知道对方的信息. 而为了维护会话信息或用户信息,一般可用Cookie或Sessi ...
- windows开通https服务
一.申请ssl证书 建议1个免费的ssl证书申请网站,已测试,可用 1.注册https://login.wosign.com/reg.html?rf=buy 2.邮箱验证登录后访问https://bu ...
- spark提示Caused by: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to [Lscala.collection.immutable.Map;
spark提示Caused by: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot b ...
- python中 staticmethod与classmethod区别
staticmethod与classmethod区别 参考 https://stackoverflow.com/questions/136097/what-is-the-difference-betw ...
- Python版求数组的最大连续区间
[本文出自天外归云的博客园] 题目:有一个数组,求他的最大(最长)连续区间(数字是连续的区间). 我的解法,如下: class Finder(object): ''' 判断两个相邻的数字是否连续,若连 ...
- wcf会话、实例化、并发
在asp.net中含有会话,是保存值,供所有的程序使用,同样在wcf中也有会话,供多个客户端使用. 会话的支持通常在契约定义的开始标出,如下 [ServiceContract(Namespace = ...
- 火狐FireFox恢复备份失败,无法处理备份文件
问题:火狐浏览器丢失书签后尝试恢复书签,按[Ctrl + Shift + B]弹出我的足迹,选择[导入和备份]-->[恢复]中任一文件,弹窗[无法处理备份文件]. 解决办法: 先找到并打开火狐浏 ...
- Javascript类型转换的规则
Javascript的变量是松散类型的,它可以存储Javascript支持的任何数据类型,其变量的类型可以在运行时被动态改变.请看示例: 1 2 3 var n = 10; n = "hel ...
- docker启动报错
1.报“can’t create unix socket /var/run/docker.sock: is a directory” 这是由于存在容器自动启动 --restart= always导致的 ...
- VS2013安装MVC5
打开VS 选择 .net 4.5 创建项目 右击项目 选择管理NuGet 输入Microsoft.AspNet.Mvc -Version 5.0.0 安装最新版本的MVC5