繁体   English   中英

用套接字解析wss协议的主机名?

[英]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地址中可以包含冒号 - 但只有它们被括在括号中。 因此,要获取netlochost部分,您需要执行以下操作:

>>> 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM