首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >连接到已关闭的域时,Python ()无法工作

问连接到已关闭的域时,Python ()无法工作
EN

Stack Overflow用户
提问于 2022-01-18 22:31:07
回答 1查看 612关注 0票数 0

我需要检查一下主机是快升还是慢。为此,我在建立连接之前添加了一个套接字超时,但套接字超时似乎不起作用。为什么?

这是我的密码:

代码语言:javascript
复制
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秒)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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。

代码语言:javascript
复制
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()
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70763180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档