Reputation: 113
I found a socket SMTP client example slightly modified for it to connect to gmail using SSLsockets, but now I don't know how to authorise account, that I am sending from. (I don't use JAVAMAIL, because this is homework)
public class SMTP {
public static void main(String args[]) throws IOException,
UnknownHostException {
String msgFile = "file.txt";
String from = "[email protected]";
String to = "[email protected]";
String mailHost = "smtp.gmail.com";
SMTP mail = new SMTP(mailHost);
if (mail != null) {
if (mail.send(new FileReader(msgFile), from, to)) {
System.out.println("Mail sent.");
} else {
System.out.println("Connect to SMTP server failed!");
}
}
System.out.println("Done.");
}
static class SMTP {
private final static int SMTP_PORT = 25;
InetAddress mailHost;
InetAddress localhost;
BufferedReader in;
PrintWriter out;
public SMTP(String host) throws UnknownHostException {
mailHost = InetAddress.getByName(host);
localhost = InetAddress.getLocalHost();
System.out.println("mailhost = " + mailHost);
System.out.println("localhost= " + localhost);
System.out.println("SMTP constructor done\n");
}
public boolean send(FileReader msgFileReader, String from, String to)
throws IOException {
SSLSocket smtpPipe;
InputStream inn;
OutputStream outt;
BufferedReader msg;
msg = new BufferedReader(msgFileReader);
smtpPipe = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(InetAddress.getByName("smtp.gmail.com"), 465);
if (smtpPipe == null) {
return false;
}
inn = smtpPipe.getInputStream();
outt = smtpPipe.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
if (inn == null || outt == null) {
System.out.println("Failed to open streams to socket.");
return false;
}
String initialID = in.readLine();
System.out.println(initialID);
System.out.println("HELO " + localhost.getHostName());
out.println("HELO " + localhost.getHostName());
String welcome = in.readLine();
System.out.println(welcome);
System.out.println("MAIL From:<" + from + ">");
out.println("MAIL From:<" + from + ">");
String senderOK = in.readLine();
System.out.println(senderOK);
System.out.println("RCPT TO:<" + to + ">");
out.println("RCPT TO:<" + to + ">");
String recipientOK = in.readLine();
System.out.println(recipientOK);
System.out.println("DATA");
out.println("DATA");
String line;
while ((line = msg.readLine()) != null) {
out.println(line);
}
System.out.println(".");
out.println(".");
String acceptedOK = in.readLine();
System.out.println(acceptedOK);
System.out.println("QUIT");
out.println("QUIT");
return true;
}
}
}
Upvotes: 0
Views: 3419
Reputation: 15
First, Make sure you have turned on 'Allow Less Secure Apps' from your Gmail. We can improve the code by ignoring the Multi-threading part by just reading the output from server. As we know from the RFC that server sends 9 lines after getting the first 'EHLO' request. So, we are just reading 9 lines with bufferedReader. Then for the next few commands, it returns only one line. So, the simplified code without multithreading will be like this :
import java.nio.charset.StandardCharsets;
import javax.net.ssl.*;
import java.io.*;
import java.util.Base64;
public class SMTP_Simplified_v2 {
// Credentials
public static String user = "[email protected]";
public static String pass = "xxxxxxxxxx";
private static DataOutputStream dataOutputStream;
public static BufferedReader br = null;
public static void main(String[] args) throws Exception {
int delay = 1000;
String username = Base64.getEncoder().encodeToString(user.getBytes(StandardCharsets.UTF_8));
String password = Base64.getEncoder().encodeToString(pass.getBytes(StandardCharsets.UTF_8));
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket("smtp.gmail.com", 465);
br = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
dataOutputStream = new DataOutputStream(sslSocket.getOutputStream());
send("EHLO smtp.gmail.com\r\n",9);
send("AUTH LOGIN\r\n",1);
send(username+"\r\n",1);
send(password+"\r\n",1);
send("MAIL FROM:<[email protected]>\r\n",1);
send("RCPT TO:<[email protected]>\r\n",1);
send("DATA\r\n",1);
send("Subject: Email test\r\n",0);
send("Email Body\r\n",0);
send(".\r\n",0);
send("QUIT\r\n",1);
}
private static void send(String s, int no_of_response_line) throws Exception
{
dataOutputStream.writeBytes(s);
System.out.println("CLIENT: "+s);
Thread.sleep(1000);
// Just reading the number of lines the server will respond.
for (int i = 0; i < no_of_response_line; i++) {
System.out.println("SERVER : " +br.readLine());
}
}
}
Upvotes: 0
Reputation: 113
Rewrote the code. This works fine.
public class TotalTemp
{
private static DataOutputStream dos;
public static void main(String[] args) throws Exception
{
int delay = 1000;
String user = "[email protected]";
String pass = "xxxxxxxx11";
String username = Base64.encodeBase64String(user.getBytes(StandardCharsets.UTF_8));
String password = Base64.encodeBase64String(pass.getBytes(StandardCharsets.UTF_8));
SSLSocket sock = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket("smtp.gmail.com", 465);
// Socket sock = new Socket("smtp.gmail.com", 587);
final BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
(new Thread(new Runnable()
{
public void run()
{
try
{
String line;
while((line = br.readLine()) != null)
System.out.println("SERVER: "+line);
}
catch (IOException e)
{
e.printStackTrace();
}
}
})).start();
dos = new DataOutputStream(sock.getOutputStream());
send("EHLO smtp.gmail.com\r\n");
Thread.sleep(delay);
send("AUTH LOGIN\r\n");
Thread.sleep(delay);
send(username + "\r\n");
Thread.sleep(delay);
send(password + "\r\n");
Thread.sleep(delay);
send("MAIL FROM:<[email protected]>\r\n");
//send("\r\n");
Thread.sleep(delay);
send("RCPT TO:<[email protected]>\r\n");
Thread.sleep(delay);
send("DATA\r\n");
Thread.sleep(delay);
send("Subject: Email test\r\n");
Thread.sleep(delay);
send("Test 1 2 3\r\n");
Thread.sleep(delay);
send(".\r\n");
Thread.sleep(delay);
send("QUIT\r\n");
}
private static void send(String s) throws Exception
{
dos.writeBytes(s);
System.out.println("CLIENT: "+s);
}
}
Upvotes: 2