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。
我可以通过端口 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。