Java - SSL - 使用 gmail 的 SMTP 服务器进行身份验证

Java - SSL - Authenticating with gmail's SMTP server

我可以通过端口 465 连接到 smtp.gmail.com。在使用 AUTH LOGIN 命令后收到一个 334 VXNlcm5hbWU6,解码后是 "Username:"

我似乎不知道如何通过服务器发送我的用户名。我正在对用户名进行编码并发送,但没有收到回复。下一个回复应该是询问我的密码。

见下文:

public class MailComponent{
Socket socket = null;
final static String MAIL_SERVER = "smtp.gmail.com";
final static int SMTP_PORT = 465;
String uName = "example@gmail.com";
String encodedName = Base64.getEncoder().encodeToString(uName.getBytes(StandardCharsets.UTF_8));

public MailComponent(){ /*Create constructor later*/}

public void sendMail() throws Exception{

    try{
        // Establish TCP Connection With Mail Server
        socket = ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(MAIL_SERVER, SMTP_PORT);

        // Create a Buffered Reader to read one line at a time
        InputStream inStream = socket.getInputStream();
        InputStreamReader inReader = new InputStreamReader(inStream);
        BufferedReader bReader = new BufferedReader(inReader);

        // Read Server's Greeting
        String serverResponse = bReader.readLine();
        System.out.println("Server Greeting: " + serverResponse);           
        if (!serverResponse.startsWith("220")){
            throw new Exception("220 Reply Not Received From Server!");
        }

        // Reference socket's output stream
        OutputStream oStream = socket.getOutputStream();

        // Send HELO command
        String heloCommand = "HELO smtp.gmail.com\r\n";
        oStream.write(heloCommand.getBytes("US-ASCII"));
        serverResponse = bReader.readLine();
        System.out.println("HELO Response: " + serverResponse);
        if (!serverResponse.startsWith("250"))
            throw new Exception("250 Reply Not Received From Server!");

        // Obtain Authorization
        String authCommand = "AUTH LOGIN\r\n";
        oStream.write(authCommand.getBytes("US-ASCII"));
        serverResponse = bReader.readLine();
        System.out.println("Auth Response: " + serverResponse);

        // Give Username
        oStream.write(encodedName.getBytes(StandardCharsets.UTF_8));    
        serverResponse = bReader.readLine();
        System.out.println("Username Response: " + serverResponse);

似乎一切正常,但发送用户名后我没有收到任何回复。关于为什么会这样有什么想法吗?

连接到 outlook.com 或 Office 365 SMTP 服务器时,您必须在端口 587 上使用 TLS - 否则它们将不会接受连接。

一旦要求输入用户名,您必须将其编码并发送 CR/LF,正如 Dmitry Streblechenko 在他最后的评论中添加的那样。但是,如果您将用户名与 CL/LF 一起发送,服务器将认为它是用户名或密码的一部分,并继续等待客户端响应。我通过简单地在单独的消息中发送它们来让它工作。

注意:STARTTLS 命令不是必需的,因为我使用的是 SSL。