Python:socket.recv()不接收推送消息

时间:2014-01-03 14:29:13

标签: python sockets imap

Python:socket.recv()不接收推送消息

您好,

我在Python3中编写一个基于套接字的IMAP客户端,它成功建立了与服务器的连接,成功地传输了IDLE命令,但随后无法从服务器接收传入的数据。

如果您想知道为什么我不使用libimap或者某些东西,答案很简单:我只想实现一个支持IDLE命令的python客户端,必须在没有该库的情况下编写。

摘录:

import socket

def runIMAPPeek():
    #socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(29 * 60)

    #connection
    s.connect((IMAP_SERVER , 443))

    #login
    data = b"a1 LOGIN " + USER + b" " + PASSWORD + b"\n"
    s.sendall(data)
    reply = read(s)

    #Idle loop
    #As in RFC 3501 connection will be reinitialized every 29 minutes
    while True:
        # Idle command
        print("#Sending IDLE...")
        data = b"a2 IDLE\n"
        s.sendall(data)
        reply = read(s)
        if reply.startswith("+ idling"):
            print(" #idling.")
        else:
            print(" #Unexpected answer: {}".format(reply))
            #sys.exit()

        # waiting for incoming mails ----------------------------------
        try:
            push_msg = read(s)
            # got push message = new message arrived
            getNewEnvelope(s, push_msg)

        except socket.timeout:
            # timeout
            print(" #timeout. Reinitializing IDLE...")
        #TODO: except (KeyboardInterrupt, SystemExit)

        # Quit Idle
        data = b"DONE\n"
        write(s, data)
        reply = read(s)
        if reply.startswith(prefix_str + " OK"):
            print(" #quit idling.")
        else:
            print(" #Unexpected answer: {}".format(reply))
            #sys.exit()


def read(s):
    """Read socket data, print it, convert to string, replace new lines
    and return it.
    """
    print("#Receiving...", end=" ")
    reply = s.recv(4096)
    reply = str(reply)[2:-1] #convert and remove byte indicators
    reply = reply.replace("\\r\\n", "\n")
    print(reply)
    return reply

问题标有“----”。虽然在邮箱中收到消息,但python没有反应但仍处于空闲/接收状态。实际上,甚至不打印s.recv()命令上方的打印行。 我用Telnet成功尝试了一切,所以没有服务器问题。

2 个答案:

答案 0 :(得分:0)

除了上面的评论,您还没有选择INBOX。你不会收到任何推送消息,因为你没有告诉它你想要什么文件夹。从技术上讲,IDLE在未选择状态下无效。

答案 1 :(得分:0)

像这样构造:

if reply.startswith("+ idling"):

完全不合规。 IDLE RFC指定客户端应该期望一个延续请求,而不是这个特定的字符串(这也恰好是一个连续请求)。