Python的imaplib是否允许您设置超时?

时间:2014-06-26 05:03:11

标签: python imaplib

我正在查看Python的imaplib的API。

据我所知,没有办法像smtplib那样设置超时。

这是对的吗?如果您不希望它阻止,您将如何处理无效的主机?

3 个答案:

答案 0 :(得分:16)

imaplib模块没有提供设置超时的方法,但您可以通过socket.setdefaulttimeout为新套接字连接设置默认超时:

import socket
import imaplib
socket.setdefaulttimeout(10)
imap = imaplib.IMAP4('test.com', 666)

或者您也可以使用imaplib.IMAP4和docs中的一些知识来覆盖imaplib source课程,这样可以提供更好的控制:

import imaplib
import socket

class IMAP(imaplib.IMAP4):
    def __init__(self, host='', port=imaplib.IMAP4_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_PORT):
        self.host = host
        self.port = port
        self.sock = socket.create_connection((host, port), timeout=self.timeout)
        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')

请注意,在创建连接后,我们应该将套接字超时设置回None以使其进入后续socket.makefile调用的阻止模式,如方法文档中所述:

  

...   套接字必须处于阻塞模式(它不能超时)。 ...

答案 1 :(得分:2)

import imaplib
...
# ssl and timeout are config values
# connection to IMAP server
if ssl:
    imapResource = imaplib.IMAP4_SSL(server, port)
else:
    imapResource = imaplib.IMAP4(server, port)
# communications timeout
sock=imapResource.socket()
timeout = 60 * 5 # 5 minutes
sock.settimeout(timeout)

答案 2 :(得分:0)

如果您想要IMAP4_SSL,我们可以进行修改 通过使用ssl上下文ssl_context.wrap_socket()

包装套接字,从而 famousgarkin's 的答案
import imaplib
import socket

class IMAP(imaplib.IMAP4_SSL):
    def __init__(self, host='', port=imaplib.IMAP4_SSL_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4_SSL.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_SSL_PORT):

        sock = socket.create_connection((host, port), timeout=self.timeout)
        self.sock = self.ssl_context.wrap_socket(sock, server_hostname=host)

        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')