在python中有socket.gethostbyname(hostname)的超时值吗?

时间:2014-12-05 20:54:00

标签: python sockets

我在python中使用gethostbyname() socket将主机名转换为IPv4地址。有时,显示IP地址只需要很少的时间。我想知道每次查找是否有任何默认超时值。以下是我在程序中使用套接字的方式 -

try:
    addr = socket.gethostbyname(hostname)
except socket.gaierror:
    addr = "" 
print hostname+" : "+addr

只需要添加另一个问题,是否有可能错过任何IP地址?任何人都有将大型主机名样本转换为IP地址的经验吗?

2 个答案:

答案 0 :(得分:1)

这是整个Socket超时文件。

import socket

try:
    _GLOBAL_DEFAULT_TIMEOUT = socket._GLOBAL_DEFAULT_TIMEOUT
except AttributeError:
    _GLOBAL_DEFAULT_TIMEOUT = object()

如您所见,GLOBAL_DEFAULT_TIMEOUT = object()只是创建一个空对象。

socket.setsocketimeout将设置新套接字的默认超时,但是如果您不直接使用套接字,则可以轻松覆盖该设置。

有关详情,请参阅this answer

编辑:至于你的后续问题,是的。我制作了一个程序,涉及IP地址转换的主机名,我确实遇到了缺少地址的问题。不确定这是否是因为超时。我只需要仔细检查一下。

答案 1 :(得分:1)

以下是使用警报信号(对于posix类型系统)设置socket.gethostbyname超时的示例:

设置代码:

from contextlib import contextmanager
import signal

def raise_error(signum, frame):
    """This handler will raise an error inside gethostbyname"""
    raise OSError

@contextmanager
def set_signal(signum, handler):
    """Temporarily set signal"""
    old_handler = signal.getsignal(signum)
    signal.signal(signum, handler)
    try:
        yield
    finally:
        signal.signal(signum, old_handler)

@contextmanager
def set_alarm(time):
    """Temporarily set alarm"""
    signal.setitimer(signal.ITIMER_REAL, time)
    try:
        yield
    finally:
        signal.setitimer(signal.ITIMER_REAL, 0) # Disable alarm

@contextmanager
def raise_on_timeout(time):
    """This context manager will raise an OSError unless
    The with scope is exited in time."""
    with set_signal(signal.SIGALRM, raise_error):
        with set_alarm(time): 
            yield

执行代码

import socket
try:
    with raise_on_timeout(0.1): # Timeout in 100 milliseconds
        print(socket.gethostbyname(socket.gethostname()))
except OSError:
    print("Could not gethostbyname in time")