微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有时通过UDP套接字发送缓冲区时延迟

我开发了一个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] 举报,一经查实,本站将立刻删除。

相关推荐