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