最快的套接字方法,用于很多文件之间的大量数据

时间:2009-12-01 20:05:15

标签: .net c++ linux networking sockets

我正在构建一个套接字应用程序,它需要将许多小/中等大小的文件洗牌,类似于5-100kb大小的文件到很多不同的客户端(有点像Web服务器,但仍然不完全)。

我应该使用winsock(win32)中的标准poll / epoll(linux)或async套接字,还是有更多性能的方法(例如win32上的重叠i / o)?

Linux和Windows都是可能的平台!

6 个答案:

答案 0 :(得分:3)

在Linux上,使用epoll解复用多个套接字是通过TCP进行并行I / O的最快方式。

但我还要提到,为了便携性,(并且因为你似乎对Linux或Windows感兴趣),你应该研究Boost.Asio。它有一个可移植的API,但在Linux上使用epoll,在Windows上使用重叠的I / O,因此您可以构建高效的便携式网络应用程序。

此外,由于您正在使用文件,因此在执行I / O时还应实现双缓冲以获得最佳性能。换句话说,您使用两个缓冲区发送/ recv每个文件。例如,在发送端,您从磁盘读取到一个缓冲区然后通过网络发送该缓冲区,而另一个线程从磁盘读取下一个数据块到第二个缓冲区。这样,您可以将磁盘I / O与网络I / O重叠。

答案 1 :(得分:2)

在Linux上,sendfile()是专门用于将数据从文件发送到套接字的高性能API(您仍然需要使用poll进行多路复用,它只是{{1}的替代品} / read部分)。

答案 2 :(得分:2)

除了epoll之外,Linux sendfile(2)似乎更适合您在服务器端的需求。

答案 3 :(得分:1)

在Windows上,您可以尝试使用TransmitFile,它有可能通过避免内核空间提高您的性能< - >用户空间数据复制。

答案 4 :(得分:0)

不幸的是,如果你想获得最大可能的性能,你仍然需要在Windows和Linux上手工制作你的I / O代码,因为目前可用的抽象库不能很好地扩展到多个线程(如果有的话)。 / p>

如果你想要可移植性(和易用性),Boost asio可能是最好的选择,但它在多线程可伸缩性方面确实有它的局限性(参见C++ Socket Server - Unable to saturate CPU) - 我想主要的问题是集成超时处理没有过多锁定到多线程事件循环。

基本上,您希望用于获得最佳性能的是I / O完成端口,其中包含Windows上的工作线程池和边缘触发的epoll以及Linux上的工作线程池。

答案 5 :(得分:0)

不要过早优化您的计划。

假设它不是一个过早的优化,最简单的方法就是将所有数据保存在内存中。你可以根据需要mmap(),或者只是在启动时加载它们。发送已经存在于内存中的东西是不费脑子的。

话虽如此,尝试用(例如)epoll复用很多东西可能有点令人头疼,你能不能使用已经写过的东西吗?