我开发了一个MPEG-TS Streamer。 它从文件中读取数据包,并以正确的速度将它们发送到接收器。
现在一切正常,除了我经常有些滞后。 我已经在我的代码中查找了每个可能的错误。 我已经优化了我的程序,性能有点明智。
现在我用sendto()函数发送数据包所用的时间来logging日志,还logging数据包发送时间和发送时间之间的差异。
我注意到,每次数据包比平均时间要晚得多,sendto()发送前一个数据包所用的时间也比正常的要多得多。
select()监视3个或更多文件描述符
如何使脚本在Linux使用我的interpteter和工作? (#!)
如何在Windows上截取屏幕截图并将其保存为JPEG?
mmap / munmap出现问题 – 第783次迭代后出现总线错误?
如何使用gcc模仿Microsoft版本的__FUNCTION__?
这表明sendto()会导致这些延迟,每次发送数据包需要更长的时间。 我正在使用UDP套接字。
我可能是做了错误的sockets? 有可能套接字缓冲区已满,实际上发送数据包需要更长的时间? 还是我想念someting? 有没有办法来加速套接字,或使其无法完全填充缓冲区之前发送?
由于这是为了stream式传输video,我相当依赖于性能,主要是因为数据包数量高得多,所以滞后发生的高清大多数情况下。
非常感谢你。
内存在variables赋值之前不包含垃圾
NTDLL!kifastsystemcallret
GDB的前端使用VIM?
为位于不同networking的节点定义UDP套接字
我如何快速创build大(> 1GB)的文本+二进制文件与“自然”的内容? (C#)
sendto()阻塞只有两个原因:
您的外出UDP缓冲区已满,需要等待空间释放
cpu调度器只是决定做一些其他的事情,因为它可以用任何系统调用。
检查输出缓冲区的大小:
int buff_size; int len = sizeof(buff_size); err = getsockopt(s,SOL_SOCKET,SO_SNDBUF,(char*)&size,&len);
一些linux系统默认为荒谬的小发送缓冲区(只有几千字节),所以你可能需要把它设置为更大。
如果缓冲区较大,并且sendto()无论如何都会暂时阻塞(精确到多长时间),那么这可能只是做生意的成本。 即使在局域网上,当然在广域网上,延迟也会有很大的变化。
更新
要增加UDP缓冲区大小的系统限制:
sysctl -w net.core.wmem_max=1048576 sysctl -w net.core.rmem_max=1048576
您可以通过/etc/sysctl.conf添加到/etc/sysctl.conf来使其成为永久性的:
net.core.wmem_max=1048576 net.core.rmem_max=1048576
要在您的应用程序中利用此功能,您需要使用setsockopt() :
int len,trysize,gotsize; len = sizeof(int); trysize = 1048576+32768; do { trysize -= 32768; setsockopt(s,(char*)&trysize,len); err = getsockopt(s,(char*)&gotsize,&len); if (err < 0) { perror("getsockopt"); break; } } while (gotsize < trysize); printf("Size set to %dn",gotsize);
对SO_RCVBUF重复相同的操作。 循环很重要,因为许多系统默默执行的最大值小于您使用sysctl设置的最大值,并且在setsockopt()失败时,它将保持原来的值不变。 所以你必须尝试许多不同的价值观,直到你得到一个坚持。 对于不测试(gotsize == trysize)也是很重要的,因为在某些系统上设置的结果实际上与您请求的结果不一样。
与TCP不同,UDP不会缓冲数据。 源代码将有助于更好地理解事物。 你发送的数据包有多大? 在UDP中,最好将有效负载保持在MTU的大小(1500字节)
你的代码很可能工作的很好,这些延迟是由操作系统调度程序造成的。
你可以尝试“更好”你的过程。 如果这提高了性能,这是一个操作系统调度问题。
[编辑]更换接收器的东西,有一个缓冲区。 或者尝试发送比接收器真正需要的数据更多的数据 – 它确实应该有一个缓冲区。 我怀疑世界上有没有人制造机顶盒,谁不知道有网络滞后,谁已经没有破产。
从你的解释,我怀疑原因是在你的代码。 有很多原因会导致速度变慢:
操作系统可能会决定给你另一个进程控制,因为你在做I / O操作。
网络缓冲区可能已满
网络可能拥塞
病毒扫描程序可能对您正在阅读的数据感兴趣,并窃取太多的周期。
如果你在Windows上:Aero桌面呈现的东西(图形卡的IRQ通常比网卡的优先级高)。
结论:你的问题是接收器没有缓冲区。 真正有很多原因会导致UDP数据包的发送延迟,并且所有这些都不在您的代码的控制之下。
原始答复
UDP不是一个可靠的协议。 数据包不能保证数据包及时到达接收端。 UDP的开销比TCP小,但这是以可靠性为代价的。
通常的解决方案是发送比客户需求更多的数据。 因此,例如,您可以在油门全开的情况下发送前10秒钟。 这允许客户端缓存一些数据以延迟播放。
您还应该更改客户端,每隔几秒将缓存流的长度发送回服务器。 然后,服务器可以计算在全速下发送的数据包数量,以保持客户端上的缓存填满。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。