networking是我在操作系统中最糟糕的地方,请原谅我问一个不完整的问题。 我已经阅读了几个小时,但它有点儿在我的脑海里游泳。 (对于我来说,我觉得与找出networking协议相比,芯片devise很容易。)
我有一些通过套接字相互通信的networking服务。 具体来说,套接字使用fd = socket(PF_INET, SOCK_STREAM, 0);
,它会自动获取TCP / IP。 我需要这个作为基础的情况下,因为这些服务可能运行在不同的机器上。
但是对于一个项目,我们试图把所有这些都embedded到基于Atom Z530P的embedded式“设备”中,所以在我看来,内存复制开销是我们可以优化的。 我一直在这里读到: data-link-access-and-zero-copy和Linux_packet_mmap和packet_mmap 。
对于这种情况,可以创build如下所示的套接字: fd = socket(PF_PACKET, PF_RAW, 0);
。 还有一些其他的东西可以做,比如分配环形缓冲区,映射它们,将它们和套接字关联起来等等。看起来像限制使用sendto
和recvfrom
来传输数据。 据我所知,由于套接字是本地的,你不需要一个可靠的“stream”types套接字,所以原始套接字是适当的接口,我猜环形缓冲区是在页面粒度使用,其中每个数据包(或数据报)从页面边界开始。
在我花费大量时间来进一步调查之前,我希望有些有用的人可以帮我解决一些问题:
先谢谢您的帮助!
我过分复杂的事情和/或优化错误的东西?
有可能。 使用PF_PACKET
套接字只适用于专门的东西。 你可能想看看
检测这两个进程在同一台机器上的最简单或最好的方法是什么?
根本不要“忘记”这些信息。
Linux是否会自动执行这些操作,为在同一台机器上运行的进程进行优化?
不,你必须自己做。
我认为TCP / IP和原始数据包之间的选择比零拷贝问题重要得多。 如果您需要可靠的基于流的通信,则需要TCP / IP(即AF_INET + PF_STREAM)。 试图通过不可靠的数据包实现一个可靠的流是非常复杂的,它已经为你做了。
使用零拷贝和文件的TCP / IP的最佳方式是,像@ cnicutar所说的,sendfile(2)和splice(2)。 我想有一种方法可以在没有这些功能的情况下享受零拷贝(如果你想把数据读入内存,而不是直接写入文件),但是我不确定如何去做。
另外,Centos是开源的,所以你可以通过下载源代码并编译得到一个vmlinux文件。