簡體   English   中英

Python的2.7 socket.timeout行為

[英]Python's 2.7 socket.timeout behavior

下面是兩個簡單的python函數。 首先嘗試在666上連接到test.com域(主機名有效,但端口不是)。 第二次嘗試在端口993上連接到imap.mail.outlook.com (主機名有效,但看起來不適合公共使用/訪問)。

def fn_outlook(timeout):
    try:
        socket.create_connection(("imap.mail.outlook.com", 993), timeout=timeout)
    except socket.timeout:
        pass


def fn_test(timeout):
    try:
        socket.create_connection(("test.com", 666), timeout=timeout)
    except socket.timeout:
        pass

以下是具有不同超時的該函數的執行時間:

In [14]: %time fn_test(1)
CPU times: user 644 µs, sys: 1.07 ms, total: 1.71 ms
Wall time: 1 s

In [15]: %time fn_test(2)
CPU times: user 589 µs, sys: 1.15 ms, total: 1.74 ms
Wall time: 2 s

In [16]: %time fn_outlook(2)
CPU times: user 838 µs, sys: 2.24 ms, total: 3.08 ms
Wall time: 7.15 s

In [17]: %time fn_outlook(4)
CPU times: user 705 µs, sys: 1.18 ms, total: 1.88 ms
Wall time: 12 s

In [18]: %time fn_test(4)
CPU times: user 483 µs, sys: 795 µs, total: 1.28 ms
Wall time: 4.42 s

對於test.com連接將在timeout參數中指定的〜同一時間后timeout 但對於imap.mail.outlook.com事情變得越來越有趣 - 套接字連接會忽略超時參數。 確切地說 - 不要忽視,而是在更長的一段時間后總是超時連接。

我可能認為此行為源自imap.mail.outlook.com服務器,而不是來自套接字模塊。

首先,您可以將您的功能統一為:

def fn_connect(host, port, timeout):
    try:
        s = socket.create_connection((host, port), timeout=timeout)
    except socket.timeout:
        return None
    else:
        return s

並稱他們為:

IMAP_HOST = "imap.mail.outlook.com"
IMAP_PORT = 993
TEST_HOST = "test.com"
TEST_PORT = 666
s1 = fn_connect(IMAP_HOST, IMAP_PORT, 2)
s2 = fn_connect(TEST_HOST, TEST_PORT, 1)
#and so on....

我返回套接字以便能夠在之后正確關閉它(如果not None )。

問題在於底層套接字機制如何解析主機名; create_connection調用getaddrinfo ,並且對於返回的每個地址,它嘗試創建一個套接字並連接到它( 並且每個套接字都有你指定的超時 )。 那么,你的2個地址的結果:

  • TEST_HOSTTEST_PORT

     socket.getaddrinfo("test.com", 666) [(2, 0, 0, '', ('69.172.200.235', 666))] 
  • IMAP_HOSTIMAP_PORT

     socket.getaddrinfo("imap.mail.outlook.com", 993) [(2, 0, 0, '', ('207.46.163.247', 993)), (2, 0, 0, '', ('207.46.163.138', 993)), (2, 0, 0, '', ('207.46.163.215', 993))] 

如您所見,對於IMAP_HOSTIMAP_PORT,它返回3個單獨的地址(而對於TEST_HOSTTEST_PORT只返回一個)。 由於您指定它們都不起作用,它將嘗試連接到所有它們,導致一般超時〜比您指定的大3倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM