[英]Resolve host name of wss protocol with socket?
如何用socket解析wss协议的主机名?
我尝试过但失败了:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = socket.gethostbyname('wss://domain.tld')
wss://domain.tld
不是主机名,而是URL。 您无法使用套接字解析URL,您必须将其解析为URL以从中获取主机名,然后您可以解决该问题。 该方案是wss,http还是rsync并不重要; 任何具有netloc
字段的方案都将以相同的方式工作。
例如,使用urllib.parse
:
>>> from urllib.parse import urlparse # in 2.x it's from urlparse
>>> url = 'wss://domain.tld'
>>> bits = urllib.parse.urlparse(url)
>>> netloc = bits.netloc
>>> netloc
'domain.tld'
所以我们完成了,对吧?
不。 netloc
可以是主机,也可以是host:端口。 而且你不能只split(':')
,因为IPv6地址中可以包含冒号 - 但只有它们被括在括号中。 因此,要获取netloc
的host
部分,您需要执行以下操作:
>>> host, _, port = netloc.rpartition(':')
>>> if ']' in port: host = netloc
>>> host
'domain.tld'
现在,我们都做了,我们已经有了一个主机名或IP地址,我们可以通过socket.gethostbyname
。
但有几个注意到这一点。
首先,您不需要创建一个socket.socket
对象来调用gethostbyname
; 它是模块的顶级函数,不需要任何套接字对象。
其次, gethostbyname
不适用于IPv6,甚至在IPv4上也有一些限制,因此您可能希望使用getaddrinfo
。
所以,完成:
>>> import socket
>>> addresses = socket.getaddrinfo(host, None) # or host, port if you prefer
gaierror: [Errno 8] nodename nor servname provided, or not known
嗯,这是预料之中的,因为我们的主机名是domain.tld
,并且没有这样的域名。 但是,如果我们使用www.google.com
,我们会收到一个很好的列表,其中包含几十个IPv4地址,如果您的系统具有IPv6连接,那么也会有几个IPv6地址。 您可以只使用第一个,或者更喜欢IPv4到IPv6,反之亦然,或者在某个其他字段上进行区分。 (您还可以通过向getaddrinfo
传递更多参数来首先过滤各种字段。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.