Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
Python SO_REUSEPORT可以在Unix域套接字上使用吗?_Python_Linux_Sockets_Networking_Tcp - Fatal编程技术网

Python SO_REUSEPORT可以在Unix域套接字上使用吗?

Python SO_REUSEPORT可以在Unix域套接字上使用吗?,python,linux,sockets,networking,tcp,Python,Linux,Sockets,Networking,Tcp,Linux内核>=3.9通过设置SO\u REUSEPORT,允许在具有内核内负载平衡的进程之间共享套接字: 这如何用于AF\u UNIX类型的套接字? 它似乎只适用于TCP,而不适用于Unix域套接字 下面是一个Python测试程序: import os import socket if not hasattr(socket, 'SO_REUSEPORT'): socket.SO_REUSEPORT = 15 if True: # using TCP sockets #

Linux内核>=3.9通过设置
SO\u REUSEPORT
,允许在具有内核内负载平衡的进程之间共享套接字:

这如何用于
AF\u UNIX
类型的套接字?

它似乎只适用于TCP,而不适用于Unix域套接字

下面是一个Python测试程序:

import os
import socket

if not hasattr(socket, 'SO_REUSEPORT'):
   socket.SO_REUSEPORT = 15

if True:
   # using TCP sockets
   # works. test with: "echo data | nc localhost 8888"
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
   s.bind(('', 8888))
else:
   # using Unix domain sockets
   # does NOT work. test with: "echo data | nc -U /tmp/socket1"
   s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
   try:
      os.unlink("/tmp/socket1")
   except:
      pass
   s.bind("/tmp/socket1")

s.listen(1)
while True:
   conn, addr = s.accept()
   print('Connected to {}'.format(os.getpid()))
   data = conn.recv(1024)
   conn.send(data)
   conn.close()
启动2个实例,并通过多次运行以下程序进行测试:

  • TCP的回显数据| nc localhost 888
  • echo data | nc-U/tmp/socket1
    用于Unix域套接字

当使用TCP时,传入的客户端将平衡到两个服务器。使用Unix域套接字,传入的客户端都会连接到上次启动的服务器。

此特定的内核修补程序记录在此处:


从修补文件列表中可以看到,修补程序只影响
net/ipv4
net/ipv6
套接字。Unix域套接字在
net/Unix
中实现。因此,答案是:不,So_REUSEPORT将不适用于AF_UNIX类型的套接字。

一个小补丁,它在UNIX套接字上增加了对
So_REUSEPORT
的支持,但已被拒绝。但是,此修补程序没有在多个套接字上实现负载平衡,它只会导致
bind()
在套接字文件已经存在的情况下不会失败

此用例被视为

从用户的角度来看,这是一个非常奇怪的角落案例


因此,仍然有可能接受另一个补丁,该补丁将通过
为UNIX套接字实现负载平衡,因此_REUSEPORT

您参考的文章的第一句:
3.9开发周期中合并的功能之一是对sou重用端口套接字选项的TCP和UDP支持
。它似乎只支持TCP和UDP。我没有确切的答案,但看起来内核没有负载平衡UNIX套接字的方法。这里有很多有用的信息:@AlexShkop谢谢!FWIW,我可以在UDS上设置选项,这将允许多个进程打开相同的UDS(侦听)。如果未设置该选项,则不允许这样做。但是,它没有负载平衡。我正在寻找一个权威的答案,要么支持观察到的行为,要么展示如何做LB平衡共享UDS。谢谢这是一个权威性的答案-虽然它是否定的=(很抱歉让你失望。但也许你可以切换到常规套接字?答案似乎仍然是最新的。我仍然希望权威更新:)谢谢你的指点!我仍然认为这个用例是有效的和重要的:拥有一个安全、高性能、低开销的IPC机制,它建立在已建立的用户API(UDS上的套接字)之上。当然,现在还有其他IPC机制(netmap、DDPK)。。但与几十年前的Posix套接字API和UDS相比,这些通常更为复杂。