【问题标题】:How to determine the end of a SMTP and POP response?如何确定 SMTP 和 POP 响应的结束?
【发布时间】:2011-12-08 05:58:10
【问题描述】:

我正在从连接到 SMTP 和 POP 服务器的套接字写入的 BufferedReader 中逐字符读取套接字响应。但是我怎么知道我是否已经阅读到响应结束以避免让read() 挂起以读取超出服务器响应的内容?以下代码是我从 BufferedReader 读取的方式:

boolean endOfResponse = false;
while(!endOfResponse) {
    c = in.read();
    if ((c >= 32 && c < 127) || c == '\t' || c == '\r' || c == '\n') { 
        response.append((char)c);
        //The following check has a problem: If the response has multiple lines, the other lines will not be read.
        if(c == '\n') endOfResponse = true;
    }
}

例如,在 POP 中,当我执行 LIST 时,响应以 . 结束。但是在 SMTP 中,当我执行 EHLO 时,它并没有明确指示响应何时结束。

遗憾的是,in.read() == -1 的使用不起作用,因为它仍会尝试读取响应数据之外的内容并导致套接字挂起。

那么,如何确定 SMTP 和 POP 响应的结束?更好的是,是否可以事先知道我应该从缓冲区读取多少字节,这样我什至不必检查响应结束?

【问题讨论】:

  • 您知道 JavaMail 的存在,实现了所有这些协议并在它们之上提供了一个抽象层吗? oracle.com/technetwork/java/javamail/index.html。即使你不想使用它,它也是开源的,所以你可能想看看它在内部是如何工作的。

标签: java sockets smtp pop3


【解决方案1】:

在 SMTP 中,事务服务器端的响应结束可以通过查看响应代码后面的字符来确定:除了最后一行之外,响应的每一行的状态代码后面都是一个“-” --

Client: EHLO my.mailserver.com
Server: 123-This is a
Server: 123 Multi-line response

因此,对于 SMTP(我之前没有处理过 POP,但听起来您已经解决了这个问题!),您需要检查状态代码后是否存在此“-”字符以确定响应中是否有更多行。

当前的 SMTP RFC (5321) 记录了这一点:https://www.rfc-editor.org/rfc/rfc5321(例如第 32 页)

【讨论】:

    【解决方案2】:

    这两种协议不同,但都发送以换行符结尾的消息。使用 SMTP,您一次读取 1 行(以 \n 结尾),您读取的每一行应以 3 个数字开头,然后是空格或“-”,如果是空格,则服务器响应结束,如果它是一个“-”(例如 250-VRFY,如果您使用 EHLO 打开,提示服务器以扩展 ESMTP 命令列表响应),那么您需要阅读另一行。

    对于 POP3,我相信这取决于您发出的命令。像 USER 或 PASS 这样的东西会给你一个“+”或“-”响应(后跟一个代码和一些文本)。像 LIST 这样的命令会给你一个“+”或“-”,如果是“+”,你会得到你的电子邮件列表,它会以一个“。”结尾。通过它自己。这些响应中的每一个(以及电子邮件的每个索引)都将是一行。

    您应该查看RFC 821 for SMTPRFC 1939 for POP3 以获取协议的详细说明

    【讨论】:

    • 那么在POP中,不同的命令有不同的结尾?对于 LIST 和 RETR,它们以 . 结尾。但是对于某些命令,如 USER 和 PASS,响应不会以 . 结尾。所以在我的代码中,我必须区分不同的命令,并且不能有一个通用的方式来读取所有命令的响应?
    • 是的,您需要知道您是否期待 POP3 的多行响应。例如,如果你发出一个 LIST,你必须阅读直到你得到一个“.”。自己在一条线上。即使没有什么可列出的。
    • Jordan Stewart 发布了最新的 RFC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 2012-02-24
    • 2021-02-26
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多