最近在做局域网投屏相关,发现使用vlc做推流和接受,延迟过大(1s以上),改用live555推流和接受,延迟还是过大,局域网中还打不到<200ms的延迟。于是乎研究了好一阵子live555源代码,也没有发现其代码层面故意的休眠的情况出现,苦思冥想数日,不得解,直到这个阳光明媚的周六,突然就想到一个方法,排除live555代码,有没有一个方法来直接了当地验证网络本来就性能不够呢,虽然说是局域网,似乎这个怀疑本生就不太然人觉得可靠。 周六就在家敲起了代码:
测试的代码是这样的:
live555推流----局域网延迟的分析

一个服务端,一个客户端,tcp建立连接,服务端以每秒30帧,(每个SendFrame操作之间休眠 usleep(100*10000/30)),每帧分成1500 Byte的小帧多次发送(小帧之间的发送间隔时间,不休眠)。服务端记录下发送端每一次发送一帧前的时间点,图中Time_send,客户端记录下每一帧接受完的时间点Time_reciv. 这两个时间差,即一帧数据的传输延迟。(前提是服务端和客户端都有相同的系统时间的情况下,记录的时间才有参考价值,为保证这一点,先在一个系统上测试,这里在虚拟机上 开启两个终端,使用本地回环网络 127.0.0.1 ,一个终端作为server, 另一个终端作为client。 同时为方便比较,记录下时间的同时也把整个发送/接受到的数据一并写入了log文件。)结果如下:
live555推流----局域网延迟的分析
可以看到,竟然达到了975231-736331=238900 微秒,也就是239毫秒。这可是本地回环网络,虽然我的环境是虚拟机ubuntu,这结果,相当不能接受。回头来看,每一次发送一帧,300Kb, 分成了205个小包发送。每一个包调用一次sendto() 发送。如果把上面的rtp分包操作去掉,不进行分包,直接调用一次 sendto()发送300Kb. 测试结果
live555推流----局域网延迟的分析
298075-296098=1977微秒,也就是2ms. 这,才是应该有的速度。。。。。。。
如果说硬要强行解释一番的话,只能说,sendto() 系统调用,需要消耗资源,要尽量减少频繁调用,上诉的一帧数据分成 205 次sendto()发送,明显比一次调用sendto() 耗时多得多。 而mtu分包,内核的tcp/ip协议栈会自行处理,如期交给应用层自己分包,多次调用系统调用sendto,还不如一次调用sendto,分包工作就交给 tcp/ip 协议栈自行处理。
至于为什么RTP要在应用层协议自己分包,还不太明白。总之,live555也好,vlc也好,发送rtp都在应用层(rtp层)自行分了包,也就是上面的200多ms延迟的做法。

测试代码后续github上传。

相关文章:

  • 2021-10-20
  • 2021-11-20
  • 2022-03-09
  • 2021-10-09
  • 2021-08-15
  • 2022-12-23
猜你喜欢
  • 2022-01-09
  • 2021-12-25
  • 2021-11-28
  • 2022-03-06
  • 2019-06-03
  • 2021-11-28
  • 2021-06-21
相关资源
相似解决方案