我正在使用 UNIX 域套接字将套接字文件描述符传递给 Python 3 程序。我想查询套接字并确定其地址族。
在此answer getsockname
系统调用用于在 C 中实现相同的结果。但是,Python 的 socket.getsockname
函数不返回地址族,而是假设调用者已经知道它.此外,它仅适用于套接字,不适用于文件描述符,并且从文件描述符创建套接字对象也需要传递地址族。
有没有办法从 Python 查询地址族?
编辑:我想强调的是,我正在寻找一个已经打开的套接字的地址族,我有它的文件描述符。
最佳答案
您只需将文件描述符传递给 socket.socket
,将其作为 fileno=
关键字属性。套接字类确定与文件描述符对应的套接字类型。然后,您可以按照@klaus 的建议找到这个家庭:使用 s.family
。
import socket
s = socket.socket()
print("original socket", s)
desc = s.fileno()
print("file descriptor", type(desc), desc)
new_s = socket.socket(fileno=desc)
print("new socket", new_s.family, int(new_s.family))
这里我在 python 中创建一个套接字,然后从套接字对象中提取文件描述符(生成一个包含描述符编号的普通 int
),以演示将其放回一个新的套接字对象。运行上面的结果:
original socket <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>
file descriptor <class 'int'> 3
new socket AddressFamily.AF_INET 2
编辑
嗯...上述方法似乎不适用于 AF_INET6
套接字,至少在我的 python 3.5.2 版本中是这样。
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
new_s = socket.socket(fileno=s.fileno())
print(new_s)
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('::%1', 0, 0, 1)>
这对我来说似乎是一个明显的错误。文档说:
If fileno is specified, the values for family, type, and proto are auto-detected from the specified file descriptor.
您可能需要检查 new_s.laddr
并启发式地确定系列。 (对于 AF_INET6
,laddr
将是 4 元组,而 AF_INET
使用 2 元组)。如果您需要 AF_UNIX
或其他系列,您可能需要对其进行扩展。
关于python - 在 Python 中查询现有套接字的地址族,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51798251/