SMTP client for Gmail on java using sockets authentication issue - java

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 = "from#gmail.com";
String to = "to#gmail.com";
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;
}
}
}

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 = "xxxxx#gmail.com";
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:<XXXXXXXX#gmail.com>\r\n");
//send("\r\n");
Thread.sleep(delay);
send("RCPT TO:<YYYYYYYY#gmail.com>\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);
}
}

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 = "xxxxxxx#gmail.com";
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:<xxxxxxxx#gmail.com>\r\n",1);
send("RCPT TO:<xxxxx#gmail.com>\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());
}
}
}

Related

Why did the server receive the first message but not the second message ("how are you")? (multithreaded java socket programming)

I am trying to create a text messaging program with three files (main function file, client file, server file)
If "-l" is present on the command line, it will run as a server, otherwise it will run as a client
Command line arguments to run server:
java DirectMessengerCombined -l 3000
Command line arguments to run client:
java DirectMessengerCombined 3000
All three files need to be able to access String args[] in the main function file because that is how it gets the port number
Screenshot of error (Server on left, client on right):
The problem with this screenshot is that the "how are you" message is never received by the server (left window)
Code of Server file (DirectMessengerServer):
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
public class DirectMessengerServer
{
private String[] serverArgs; // <-- added variable
private static Socket socket;
public boolean keepRunning = true;
int ConnectOnce = 0;
public DirectMessengerServer(String[] args) throws IOException
{
// set the instance variable
this.serverArgs = args;
run();
}
public String[] ServerRun(String[] args) throws IOException
{
//How do I get the String[] args in this method be able to access it in the run methods?
serverArgs = args;
serverArgs = Arrays.copyOf(args, args.length);
return serverArgs;
}
Thread ListeningLoop = new Thread();
//run method of ServerRecieve
public void run() throws IOException
{
try
{
if(ConnectOnce == 0)
{
int port_number1 = Integer.valueOf(serverArgs[1]);
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
ConnectOnce = 4;
}
while(keepRunning)
{
//Reading the message from the client
//BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromClient = br.readLine();
System.out.println("Message received from client: "+ MessageFromClient);
// ServerSend.start();
runSend();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
Thread ServerSend = new Thread ();
//Run method of ServerSend
public void runSend()
{
while(keepRunning)
{
System.out.println("Server sending thread is now running");
try
{
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
run();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
}
}
Code of client (DirectMessengerClient):
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerClient
{
private String[] clientArgs; // <-- added variable
private static Socket socket;
public boolean keepRunning = true;
public DirectMessengerClient(String[] args) throws IOException
{
// set the instance variable
this.clientArgs = args;
run(args);
}
public String[] ClientRun(String[] args)
{
clientArgs = args;
clientArgs = Arrays.copyOf(args, args.length);
return clientArgs;
}
Thread ClientSend = new Thread();
public void run(String args[]) throws IOException
{
System.out.println("Client send thread is now running");
while(keepRunning)
{
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
int port = Integer.valueOf(port_number1);
String host = "localhost";
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
runClientRead(args);
}
}
Thread ClientRead = new Thread();
public void runClientRead(String args[]) throws IOException
{
System.out.println("Client recieve/read thread is now running");
//Integer port= Integer.valueOf(args[0]);
//String host = "localhost";
//InetAddress address = InetAddress.getByName(host);
//socket = new Socket(address, port);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromServer = br.readLine();
System.out.println("Message received from server: " + MessageFromServer);
}
}
Code of main function file (DirectMessengerCombined):
import java.io.IOException;
public class DirectMessengerCombined
{
public static void main(String[] args) throws IOException
{
DirectMessengerClient client1 = null;
DirectMessengerServer server1 = null;
for (int i = 0; i < args.length; i++)
{
if (args.length == 1)
{
client1 = new DirectMessengerClient(args);
client1.ClientRun(args);
}
else if (args.length == 2)
{
server1 = new DirectMessengerServer(args);
server1.ServerRun(args);
}
i=args.length + 20;
}
}
}
My question is: Why is the server able to accept the first message but not able to accept the second message ("how are you")?

Browser not displaying basic http server response

Have a task to create a basic http server. I've gotten to the point where it asks you to send text response back that should be displayed in your browser if you go to http://localhost:8080/ but I just get a page cannot be displayed error. I think it must be something to do with the format of the response I'm sending but i just can't get it. Any help would be much appreciated.
import java.net.*;
import java.io.*;
import java.util.*;
class HttpServer{
public static void main(String[] args){
try{
ServerSocket ss = new ServerSocket(8080);
while(true){
HttpServerSession sesh = new HttpServerSession(ss.accept());
sesh.start();
}
}catch(IOException e){
System.err.println("IOException");
}
}
}
class HttpServerSession extends Thread {
private Socket client;
public HttpServerSession(Socket client){
this.client = client;
}
private void println(BufferedOutputStream bos, String s) throws IOException {
String news = s + "\r\n";
byte[] array = news.getBytes();
for(int i = 0; i < array.length; i++){
bos.write(array[i]);
}
return;
}
public void run(){
try{
InetAddress clientIP = client.getInetAddress();
System.out.println("We just got a message! " + clientIP.getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String request = reader.readLine();
System.out.println(request);
String[] parts = request.split(" ");
if(parts.length == 3){
BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
String filename = parts[1].substring(1);
if(parts[0].equals("GET")){
while(true){
String line = reader.readLine();
System.out.println(line);
if(line == null || line.equals("")){
break;
}
}
println(bos, "OK");
println(bos, "");
println(bos, "Hello World");
}
}
client.close();
}catch(Exception e){
System.err.println("Exception in thread");
}
}
}
Turns out I just had to flush the BufferedOutputStream

unknown host exception when I try to send request

I'm trying to check whether several pors are open and if 80 port is open - send http request and then show result in console. Every port is checked in his own thread.
I send requests like this
public static void send(Socket sock, String host) throws IOException{
PrintWriter pw = new PrintWriter(sock.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: " + host);
pw.println("");
pw.flush();
}
In class TCPClient I use it and return result as bytes and then show it console.
try {
sock = new Socket(host, port);
System.out.println("port " + port + " is in use");
// send request
HttpSender.send(sock, host);
BufferedReader bf = new BufferedReader(new InputStreamReader(sock.getInputStream()));
StringBuffer response = new StringBuffer();
String line = "";
while((line = bf.readLine()) != null) {
response.append(line);
response.append('\r');
}
bf.close();
return String.valueOf(response).getBytes(); // in method run I show it
} catch (SocketException e) {
return ("port " + port + " is free").getBytes();
}
I create pool of threads for port checking.
public class ThreadPool {
private static int MAX_THREADS = 5;
private static String DESTINATION = "http://stackoverflow.com/";
private ExecutorService es = null;
public ThreadPool() {
es = Executors.newFixedThreadPool(MAX_THREADS);
}
public void perform(int start, int end) throws UnknownHostException {
for (int i = start; i <= end; i++) {
Runnable req = new TCPClient(DESTINATION, i);
es.execute(req);
}
es.shutdown();
while (!es.isTerminated()) {
}
;
System.out.println("all ports checked!");
}
}
When I set destination as www.stackoverflow.com and got document with text that it was moved permanently to http://stackoverflow.com/. When I set this destination - I've got UnknownhostException.
Where is the problem?
Have you tried private static String DESTINATION = "stackoverflow.com";? The string "http://stackoverflow.com" isn't a hostname, it's a URL.

Server/client String[] array over Socket connection

I'm trying to send a String[] over an open socket connection but it's doesn't work.
I went to send an array from database and sending result set on client after a socket connection!
Server
public class ServerConnectionHandler implements Runnable {
private static String String;
private Socket clientSocket;
public ServerConnectionHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public String[] toStringArray(ResultSet resultSet, String columnLabel) {
LinkedList<String> resultList = new LinkedList<String>();
try {
while (resultSet.next()) {
resultList.add(resultSet.getString(columnLabel));
}
} catch (SQLException e) {
e.printStackTrace();
}
return resultList.toArray(new String[0]);
}
#Override
public void run() {
ResultSet val = null;
System.out.println("Client " + clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " has connected.");
Mysql conn = new Mysql("****", "root", "","*****");
val = conn.executeSelect(CONSTANT.QUERY_ALL);
String[] mybytearray = toStringArray(val,"real_url");
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputline, outputline;
outputline = "Connected to server...type in the console to interact!";
out.println(outputline);
while((inputline = in.readLine()) != null){
outputline = "Server echoes: " + mybytearray;
out.println(outputline);
}
}
catch(Exception e) {
System.out.println("Client " + clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " has disconnected.");
}
}
}
Client
public class ClientMain {
private String host;
private int port;
public ClientMain(String host, int port) {
this.host = host;
this.port = port;
}
public void start() {
try {
Socket clientSocket = new Socket(host, port);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputline, outputline;
while((inputline = in.readLine()) != null){
System.out.println(inputline);
outputline = getUserInput();
out.println(outputline);
}
}
catch (Exception e) {
System.out.println("Server not running, shutting down...");
System.exit(-1);
}
}
private static String getUserInput() {
String s = "";
InputStreamReader isr;
BufferedReader br;
try {
isr = new InputStreamReader(System.in);
br = new BufferedReader(isr);
s += br.readLine();
}
catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
return s;
}
}
Besides the overall flawed design, I'm pretty sure this line is very wrong:
outputline = "Server echoes: " + mybytearray;
You're concatenating a string "Server echoes: " with an array. You can't do this.
Instead, try this:
outputline = "Server echoes: ";
for (String s : mybytearray) {
outputline += s;
}
But why on earth you call array of String mybytearray?
As a career advice consider using debugger facility available in every modern Java IDE.

Java Server Sockets: My Server Socket only allows client connections running on the same internet connection?

Ok so I have constructed a working example of a client and server which can accept multiple client connections. My problem is is that I cannot connect a client which is not running the same internet connection as the one the server is being hosted on. Is this possible using server sockets?
Here is the code for my server:
import java.io.IOException;
import java.net.*;
public class MultipleSocketServer {
public static Socket connection;
public static String name = "Tyler's Server";
public static int limit = 2;
public static Thread[] clients = new Thread[limit];
public static int current = 0;
public static int port = 25565;
public static String[] connected = new String[limit];
public static ServerSocket socket;
public static void main(String[] args) {
System.out.println("Server starting...");
for(int i = 0; i < limit; i++) {
connected[i] = "";
}
try {
ServerSocket socket = new ServerSocket(port);
while(true) {
Socket connection = socket.accept();
String ip = connection.getRemoteSocketAddress().toString().substring(1, 13);
loop:
for(int i = 0; i < connected.length; i++) {
if(connected[0].equals(ip) || connected[1].equals(ip)) {
break loop;
}else if(!connected[i].equals(ip)) {
connected[i] = ip;
MultiServer_Client client = new MultiServer_Client(connection, i);
Thread run = new Thread(client);
run.start();
break loop;
}
}
}
} catch (IOException e1) {
System.out.println("Could not bind server on: " + port);
System.exit(-1);
}
}
}
And here is the rest:
import java.io.*;
import java.net.Socket;
public class MultiServer_Client implements Runnable {
public String time;
public Socket client;
public StringBuffer process = new StringBuffer();
public BufferedInputStream inputStream;
public InputStreamReader reader;
public BufferedOutputStream outputStream;
public OutputStreamWriter writer;
public StringVis check = new StringVis("");
public StringChangeListener checkListener = new StringChangeListener() {
public void textChanged(StringChangeEvent e) {
System.out.println("Changed");
write("Server recieved message...");
}
};
public boolean connected = true;
public int ID;
public MultiServer_Client(Socket connection, int i) {
client = connection;
ID = i;
try {
//declare text input/output
inputStream = new BufferedInputStream(client.getInputStream());
reader = new InputStreamReader(inputStream);
outputStream = new BufferedOutputStream(client.getOutputStream());
writer = new OutputStreamWriter(outputStream, "US-ASCII");
} catch (IOException e) {
System.out.println("IOException: " + e);
}
System.out.println(MultipleSocketServer.connected[ID] + " connected...");
write("Connected to " + MultipleSocketServer.name);
}
public void run() {
while(connected) {
read();
}
System.out.println("Disconnecting client...");
}
public void write(String authen) {
try {
time = new java.util.Date().toString();
String message = time + ": " + authen + (char) 13;
writer.write(message);
writer.flush();
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
public void read() {
//read from client
int character;
process = new StringBuffer();
try {
while ((character = reader.read()) != 13) {
process.append((char) character);
}
check.setText(process.toString());
process.delete(0, process.length());
} catch (IOException e) {
connected = false;
MultipleSocketServer.connected[ID] = "";
}
}
}
Here's the client code:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class SocketClient {
public static String host = "69.182.134.79";
public static int port = 25565;
public static void main(String [] args) {
StringBuffer imports = new StringBuffer();
String time;
System.out.println("Client starting...");
try {
//establish client
InetAddress address = InetAddress.getByName(host);
Socket connection = new Socket(address, port);
BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
while(true) {
Scanner scan = new Scanner(System.in);
String message = scan.nextLine();
//write to server
time = new java.util.Date().toString();
String process = host + ":" + port + " sent data at " + time + ": " + message + (char) 13;
osw.write(process);
osw.flush();
//read from server
int c;
while ((c = isr.read()) != 13) {
imports.append((char) c);
}
System.out.println(imports);
imports.replace(0, imports.length(), "");
if(message.equals("--EXIT")) {
connection.close();
}
}
} catch (UnknownHostException e) {
System.out.println("UnknownHostException: " + e);
} catch (IOException e) {
System.out.println("IOExcepion: " + e);
}
}
}
Change
MultiServer_Client client = new MultiServer_Client(connection, i);
to
MultiServer_Client client = new MultiServer_Client(new Socket([Server IP], port), i);
This should work.

Categories