Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux:OS对非特权进程间总线的支持_Linux_Sockets_Ipc_Broadcast - Fatal编程技术网

Linux:OS对非特权进程间总线的支持

Linux:OS对非特权进程间总线的支持,linux,sockets,ipc,broadcast,Linux,Sockets,Ipc,Broadcast,我试图找到一个简单的解决方案,用于在Linux主机上运行的非特权进程之间进行高性能广播/多播通信。我正在寻找一个1)简单、2)无特权(无根)、3)语言独立、4)面向数据包和5)高效(Gbit/s及以上)的解决方案 在上下文中,我现有的代码只是使用UDP套接字进行单播通信,这完全符合上述要求(单播除外)。我已经研究过通过让多个程序监听同一个UDP端口(使用SO\u REUSEADDR和/或SO\u REUSEPORT)将其扩展到多播,但这实际上并没有将数据包的副本分发到所有进程 我还研究了使用环回

我试图找到一个简单的解决方案,用于在Linux主机上运行的非特权进程之间进行高性能广播/多播通信。我正在寻找一个1)简单、2)无特权(无根)、3)语言独立、4)面向数据包和5)高效(Gbit/s及以上)的解决方案

在上下文中,我现有的代码只是使用UDP套接字进行单播通信,这完全符合上述要求(单播除外)。我已经研究过通过让多个程序监听同一个UDP端口(使用
SO\u REUSEADDR
和/或
SO\u REUSEPORT
)将其扩展到多播,但这实际上并没有将数据包的副本分发到所有进程


我还研究了使用环回广播(127.255.255.255)来达到多个监听进程,但似乎我需要绑定环回设备上的多个IP地址才能工作,添加这些地址需要根。

根据Pete的建议,我找到了以下解决方案,这并不太复杂

下面的Python2程序通过多播/环回实现了一个简单的聊天程序。在Linux 3.13/Ubuntu 14.04上测试

导入操作系统、套接字、系统
#使用管理范围的多播IP(RFC 2365)。
mcast_组='239.0.0.0'
端口=1234
#通过环回接口进行通信。
ifc='127.0.0.1'
def发送(数据):
sock=socket.socket(socket.AF_INET,socket.sock_DGRAM,0)
#通过环回接口发送。
sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_如果,
插座(国际金融公司)
sock.sendto(数据,(mcast_组,端口))
def listen():
sock=socket.socket(socket.AF_INET,socket.sock_DGRAM,0)
#加入小组。
sock.setsockopt(socket.IPPROTO_IP,socket.IP_添加_成员资格,
socket.inet_-aton(mcast_组)+socket.inet_-aton(ifc))
#允许多个订阅者。
sock.setsockopt(socket.SOL_socket,socket.SO_REUSEADDR,1)
sock.bind((mcast_组,端口))
尽管如此:
数据,远程=sock.recvfrom(1024)
打印“#%d(%s:%d):%s%”(os.getpid(),)+remote+(data,)
args=''.join(sys.argv[1:])
如果参数为:
发送(args)
其他:
听
通过设置
ifc='0.0.0.0'
并取消设置
IP\u多播\u IF
选项,可以轻松扩展到跨本地广播段(LAN)的通信

接收自己的流量

唯一的问题是,似乎没有简单的方法可以加入一个组并发送给组中的其他人,而不获得自己的流量(即使使用相同的套接字进行侦听和发送)

IPPROTO\u IP
socket选项
IP\u多播\u循环
不工作;它在使用环回接口时无效,并且在通过网络进行通信时,它会阻止其他本地客户端接收消息

不过,我可以通过过滤源地址来解决这个问题


(作为旁注,我刚刚意识到QEMU包括使用多播发送虚拟网络流量的功能。QEMU开发人员还讨论了基于源地址的过滤,尽管他们似乎从未对此做过任何事情。因此,QEMU VM接收其自身传出流量的副本,尽管流量通常被拒绝

您必须使用,以使所有进程都能接收到它。为此,可能值得尝试使用dbus。它通常已安装(并正在运行)默认情况下,在普通Linux操作系统中;它是健壮的;它已成为一种惯用的Linux IPC方式。我对任何涉及中间人进程的事情都持谨慎态度,因为额外的上下文切换和内存拷贝会严重影响性能。例如,发现DBus比Unix套接字慢15倍。我知道DBus peformanc已经做了很多工作e从2010年开始,但到目前为止,多播UDP似乎更简单,毫无疑问也更快速。这也适用于Windows 7,只是接收套接字必须绑定到接口单播地址或“任意”地址(0.0.0.0),而不是多播地址。因此,它也可以接收单播流量。