我使用UNIX域套接字将套接字文件描述符传递给Python 3程序。我想查询套接字并确定它的地址系列。
在这个回答中,getsockname系统调用用于在C中实现相同的结果,但是,socket.getsockname函数并不返回地址家族,而是假定调用者已经知道了。此外,它只在套接字上工作,而不是在文件描述符上工作,并且从文件描述符创建套接字对象也需要传递地址家族。
有办法从Python中查询地址家族吗?
编辑:我想强调的是,我正在寻找已经打开的套接字的地址系列,我有文件描述符。
发布于 2018-08-11 21:37:04
您只需将文件描述符传递给socket.socket,将其作为fileno=关键字属性。套接字类计算出与文件描述符对应的套接字类型。然后,你就可以像克劳斯建议的那样找到他的家人:用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套接字,至少在我的python3.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)>对我来说,这似乎是个明显的错误。文件上说:
如果指定了fileno,则从指定的文件描述符中自动检测到家族、类型和proto的值。
您可能需要检查new_s.laddr并启发式地确定家庭。(对于AF_INET6,laddr将是一个4元组,而AF_INET将使用一个二元组)。如果您希望AF_UNIX或其他家庭,您可能需要扩展这一点。
发布于 2018-08-11 11:46:12
您可以在python中查询套接字的地址系列,检查.family属性。sock对象中还保存了其他属性。
import socket
import sys
# Create a TCP/IP socket
sock = socket.create_connection(('www.stackoverflow.com', 80))
print(sock)
print(sock.family)输出是
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('x.x.x.x', y), raddr=('x.x.x.x', 80)>
AddressFamily.AF_INET发布于 2018-08-11 12:01:42
如果您只需要有关套接字的信息,我建议使用socket.getaddrinfo。
文档:
函数返回具有以下结构的5个元组的列表: (家族、类型、原语、宗教名称、sockaddr)
>>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP)
[(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>,
6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)),
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>,
6, '', ('93.184.216.34', 80))]https://stackoverflow.com/questions/51798251
复制相似问题