我需要检查一下主机是快升还是慢。为此,我在建立连接之前添加了一个套接字超时,但套接字超时似乎不起作用。为什么?
这是我的密码:
import socket
def test_hostname(hostname, port):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(1.0) # timeout
try:
s.connect((hostname, port))
except (socket.timeout, socket.gaierror):
return False
else:
return True
finally:
s.close()
result = test_hostname("001.com",80) # 001.com is down
print(result)我需要10-20秒来代替指定的超时时间(1秒)。
发布于 2022-01-18 23:24:10
之所以会出现这种情况,是因为Python套接字的超时并不限制用于DNS查找的时间。由于您使用的域名需要解析为IP,因此您的s.connect((hostname, port))首先需要对hostname进行DNS查询,只有这样,它才能使用DNS服务器返回的一个IP创建连接(如果有的话)。
域001.com似乎不解析到任何IP地址,因此系统可能需要几秒钟才能返回失败。当这种情况发生时,Python将退出,连接将失败,但是超时时间已经很长了。
如果您知道要访问的主机的IP地址,请使用该地址而不是主机名。如果没有,则必须使用DNS解析库来超时DNS解析,例如dnspython。
import socket
import dns.resolver
def test_hostname(hostname, port):
resolver = dns.resolver.Resolver()
resolver.timeout = resolver.lifetime = 1
try:
answer = resolver.resolve(hostname, 'A')
except dns.exception.Timeout:
return False
if not answer.rrset:
return False
addr = next(iter(answer.rrset)).to_text()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
try:
s.connect((addr, port))
except (socket.timeout, socket.gaierror):
return False
else:
return True
finally:
s.close()https://stackoverflow.com/questions/70763180
复制相似问题