使用此Java程序了解SMTP的工作原理(不允许使用JavaMail)

使用此Java程序了解SMTP的工作原理(不允许使用JavaMail),java,sockets,email,smtp,Java,Sockets,Email,Smtp,我不确定如何将编码的base64凭据传递到邮件服务器。有没有办法不用JavaMail就可以做到这一点?我一直遇到authentication 530 authentication required错误,我知道这是由于未正确发送凭据造成的,但我无法找出这一点 import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOExceptio

我不确定如何将编码的base64凭据传递到邮件服务器。有没有办法不用JavaMail就可以做到这一点?我一直遇到authentication 530 authentication required错误,我知道这是由于未正确发送凭据造成的,但我无法找出这一点

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.util.Base64;
import java.util.Base64.Encoder;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.net.*;


public class EmailClient
{
public static void main(String[] args) throws Exception
{
// Establish a TCP connection with the mail server.
SSLSocket socket = (SSLSocket) ((SSLSocketFactory)
SSLSocketFactory.getDefault()).
createSocket(InetAddress.getByName("smtp.gmail.com"), 465);

/* encoding the username and password in Base64 for SMTP */
Encoder base64Encoder = Base64.getEncoder();
String smtpUser = 
base64Encoder.encodeToString("username".getBytes());
String smtpPass = 
base64Encoder.encodeToString("password".getBytes());

 // Create a BufferedReader to read a line at a time.
 InputStream is = socket.getInputStream();
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader br = new BufferedReader(isr);


// Read greeting from the server.
String response = br.readLine();
System.out.println(response);
if (!response.startsWith("220")) {
throw new Exception("220 reply not received from server.");
}

// Get a reference to the socket's output stream.
   OutputStream os = socket.getOutputStream();

// Send HELO command and get server response.
   String command = "HELO alice\r\n";
   System.out.print(command);
   os.write(command.getBytes("US-ASCII"));
   response = br.readLine();
   System.out.println(response);
   if (!response.startsWith("250")) {
   throw new Exception("250 reply not received from server.");
        }
// Authentication
   String cmmd authMsg = "AUTH LOGIN\r\n"

// How do I send my encoded credentials to the server?

// Send MAIL FROM command.
   String mailFrom = "MAIL FROM: <xxxxxxxx@gmail.com>\r\n";
   System.out.print(mailFrom);
   os.write(mailFrom.getBytes("US-ASCII"));
   response = br.readLine();
   System.out.println(response);
   if (!response.startsWith("250")) {
   socket.close();
   throw new Exception("250 reply not received from server.");
        }
        // Send RCPT TO command.
        String commandRCPT = "RCPT TO:<xxxxxxxxxx.com>\r\n";
        System.out.print(commandRCPT);
        os.write(commandRCPT.getBytes("US-ASCII"));
        response = br.readLine();
        System.out.println(response);
        if (!response.startsWith("250")) {
        socket.close();
        throw new Exception("250 reply not received from server.");
        }

        // Send DATA command.
        String commandDATA = "DATA\r\n";
        System.out.print(commandDATA);
        os.write(commandDATA.getBytes("US-ASCII"));
        response = br.readLine();
        System.out.println(response);
        if (!response.startsWith("354")) {
        socket.close();
        throw new Exception("354 reply not received from server.");
        }

        // Send message data.
        String msgLine1 = "email sent\r\n";
        System.out.print(msgLine1);
        os.write(msgLine1.getBytes("US-ASCII"));

        // End with line with a single period.
        String msgLine2 = ".\r\n";
        System.out.print(msgLine2);
        os.write(msgLine2.getBytes("US-ASCII"));
        response = br.readLine();
        System.out.println(response);
        if (!response.startsWith("250")) {
        socket.close();
        throw new Exception("250 reply not received from server.");
        }

        // Send QUIT command.
        String commandQUIT = "QUIT\r\n";
        System.out.print(commandQUIT);
        os.write(commandQUIT.getBytes("US-ASCII"));
        response = br.readLine();
        System.out.println(response);
        if (!response.startsWith("221")) {
        socket.close();
        throw new Exception("221 reply not received from server.");
        }

        socket.close();
    }
}
导入java.io.BufferedReader;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.net.InetAddress;
导入java.util.Base64;
导入java.util.Base64.Encoder;
导入javax.net.ssl.SSLSocket;
导入javax.net.ssl.SSLSocketFactory;
导入java.io.*;
导入java.net。*;
公共类电子邮件客户端
{
公共静态void main(字符串[]args)引发异常
{
//与邮件服务器建立TCP连接。
SSLSocket插座=(SSLSocket)((SSLSocketFactory)
SSLSocketFactory.getDefault()。
createSocket(InetAddress.getByName(“smtp.gmail.com”),465);
/*在Base64中为SMTP编码用户名和密码*/
编码器base64Encoder=Base64.getEncoder();
字符串smtpUser=
base64Encoder.encodeToString(“username.getBytes());
字符串smtpPass=
base64Encoder.encodeToString(“password.getBytes());
//创建一个BufferedReader以一次读取一行。
InputStream=socket.getInputStream();
InputStreamReader isr=新的InputStreamReader(is);
BufferedReader br=新的BufferedReader(isr);
//从服务器读取问候语。
字符串响应=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“220”)){
抛出新异常(“220未从服务器收到回复”);
}
//获取套接字输出流的引用。
OutputStream os=socket.getOutputStream();
//发送HELO命令并获取服务器响应。
String命令=“HELO alice\r\n”;
系统输出打印(命令);
写(command.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“250”)){
抛出新异常(“未从服务器收到250个回复”);
}
//认证
字符串cmmd authMsg=“AUTH LOGIN\r\n”
//如何将编码的凭据发送到服务器?
//从命令发送邮件。
字符串mailFrom=“邮件发件人:\r\n”;
系统输出打印(mailFrom);
写(mailFrom.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“250”)){
socket.close();
抛出新异常(“未从服务器收到250个回复”);
}
//将RCPT发送到命令。
String commandRCPT=“RCPT TO:\r\n”;
系统输出打印(commandRCPT);
写(commandRCPT.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“250”)){
socket.close();
抛出新异常(“未从服务器收到250个回复”);
}
//发送数据命令。
String commandDATA=“DATA\r\n”;
系统输出打印(命令数据);
写(commandDATA.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“354”)){
socket.close();
抛出新异常(“未从服务器收到354回复”);
}
//发送消息数据。
字符串msgLine1=“已发送电子邮件\r\n”;
系统输出打印(msgLine1);
写(msgLine1.getBytes(“US-ASCII”);
//以单周期的行结束。
字符串msgLine2=“。\r\n”;
系统输出打印(msgLine2);
写(msgLine2.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“250”)){
socket.close();
抛出新异常(“未从服务器收到250个回复”);
}
//发送退出命令。
String commandQUIT=“退出\r\n”;
系统输出打印(命令退出);
write(commandQUIT.getBytes(“US-ASCII”);
response=br.readLine();
System.out.println(响应);
如果(!response.startsWith(“221”)){
socket.close();
抛出新异常(“221未从服务器收到回复”);
}
socket.close();
}
}
您显示的代码中没有发生任何事件,这就是
RCPT TO
命令失败的原因。看

您的SMTP客户端需要在连接到服务器、识别自身之后以及从/
RCPT向
/
数据
命令发送任何
邮件之前,发送一个成功的
AUTH
命令。您需要使用
EHLO
而不是
HELO
,以确定服务器实际支持哪些
AUTH
方案(
LOGIN
PLAIN
GSSAPI
DIGEST-MD5
CRAM-MD5
OAUTHBEARER
,等等),然后相应地对其中一个方案进行身份验证1

1:仅供参考,
mail.smtp2go.com
支持和验证方案。请参见更详细地描述它们的部分

有关更多详细信息,请参阅和其他相关RFC

我还建议您阅读以了解SMTP协议的一般工作原理,因为您现在掌握的代码在如何处理协议方面并不完整,特别是在如何读取服务器响应方面(请参阅)

尝试类似以下内容:

导入java.io.BufferedReader;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.net.InetAddress;
导入java.util.Base64;
导入java.util.Base64.Encoder;
导入javax.net.ssl.SSLSocket;
导入javax.net.ssl.SSLSocketFactory;
导入java.io.*;
导入java.net。*;
公共类电子邮件客户端
{
专用SSLSocket插座;
专用缓冲读取程序br;
私有输出流;
私有字符串lastResponseText;
私有的