【发布时间】:2017-04-06 09:24:42
【问题描述】:
我正在实时环境中使用 udp 套接字。我目前正在使用标准套接字函数 sendto() ,这需要相当多的时间。我读到可以使用零复制,如果我理解得很好,可以避免通过从用户/内核环境复制文件来增加额外的时间。但是,我看到sendfile() 只允许从一个文件描述符复制到另一个文件描述符。我看不出如何使用它来发送 UDP 数据包,在我的例子中是一个缓冲区。所以我的问题是:
- 甚至可以使用 sendfile() 发送 UDP 数据包吗?
- 如果是这样,正确的做法是什么?
编辑
我正在一个实时平台上工作,我有几个操作以及通过套接字发送。所有这些都不应超过 1ms。我在三台机器上试过,第一台有 4 核 3.4GHz,其他 8 核 2.3GHz,最后一台 4 核 1.4GHz。在第一个上,发送一个 720 字节的数据包需要不到 1µs 的时间。而在另外两个上,它在 6 到 9µs 之间。我使用的是 linux 低延迟内核,并停用了所有 CPU 电源管理功能,因此所有 CPU 都处于最大频率。
我注意到,如果 sendto() 所用的时间大于 6µs,则平台根本无法工作。另一种精度,我有几个线程并行运行。所以也许只是 CPU 处理其他线程,而 sendto() 还没有完成。我想知道这是可能的,在进行其他操作时停止 sendto() 。
这就是为什么我试图寻找其他解决方案在其他地方进行优化,我认为使用 sendfile() 可以避免额外的时间被保存。
【问题讨论】:
-
在 Linux(以及 Unixy 世界的其他部分)中,什么是“套接字”?它是一个描述符。仅仅因为一些文档说“文件”描述符并不意味着它必须是一个实际的“文件”。否则整个
sendfile调用将毫无用处,如果它只能复制文件。 -
@Someprogrammerdude。谢谢你。我对描述符/指针/...之间的区别不太熟悉。在我的情况下,我有一个缓冲区,其中包含我要发送的数据包。如果我理解,它不被视为与描述符相同,因此无法直接将其传递给 sendfile();对吗?
-
不,
sendfile仅在描述符之间复制。如果源是内存缓冲区,则不能使用它。然后你必须使用sendto。 -
@Someprogrammerdude。谢谢你。是否有另一种方法可以最大限度地减少套接字 sendto 所花费的时间?
-
阅读您为
sendfile()提供的文档链接我怀疑它是否可以在UDP 上可靠地工作,如果它完全可以工作的话。提到了 TCP,它是一种面向连接的流,而 UDP 是一种无连接的数据包协议。所以 TCP 的语义有点像顺序文件,而 UDP 没有。