简体   繁体   中英

Writing SMTP Client in Java without Java Mail API or any third party API

I am asking this and I am terribly embarrassed. I am implementing an SMTP client without using Java MAIL API or any other third party encryption library, open source or not as I am not fond of third party APIs and wish to do stuff my way on my terms. I know it is arrogant but it is the way I am. So, far I have this: -

import java.net.Socket;
import java.util.Scanner;
import java.util.Base64;

public class SocketSample
{
    public static void main(String[] args) throws Exception
    {
        Socket socket = null;
        InputStream in = null;
        OutputStream out = null;
        String uid = Base64.getEncoder().encodeToString("xyz@gmail.com".getBytes());
        String pwd = Base64.getEncoder().encodeToString("abc123".getBytes());
        System.out.println(uid);
        System.out.println(pwd);
        //char ans = '\0';
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter host: ");
        String host = scanner.nextLine();
        System.out.print("Enter port: ");
        int port = Integer.parseInt(scanner.nextLine());
        socket = new Socket();
        socket.connect(new InetSocketAddress(host, port));
        if (socket.isConnected())
        {

            System.out.println("Socket connected.");
            out = socket.getOutputStream();
            String command = "HELO " + host + "\r\n";
            byte[] data = command.getBytes();
            out.write(data);
            out.flush();
            //
            in = socket.getInputStream();
            int c = '\0';
            while (c != -1)
            {
                c = in.read();
                System.out.print((char) c);
            }
            //
            command = "STARTTLS\r\n";
            data = command.getBytes();
            out.write(data);
            out.flush();
            c = '\0';
            while(c != -1)
            {
                c = in.read();
                System.out.print((char) c);
            }
            /*
            command = "HELO " + host + "\r\n";
            data = Base64.getEncoder().encodeToString(command.getBytes()).getBytes();
            out.write(data);
            out.flush();
            c = '\0';
            while(c != -1)
            {
                c = in.read();
                System.out.print((char) c);
            }
            */
            System.out.println(uid);
            System.out.println(pwd);
            command = "AUTH PLAIN " + uid + "\r\n";
            data = command.getBytes();
            out.write(data);
            out.flush();
            c = '\0';
            while(c != -1)
            {
                c = in.read();
                System.out.print((char) c);
            }
            //
            command = pwd + "\r\n";
            data = command.getBytes();
            out.write(data);
            out.flush();
            c = '\0';
            while (c != -1)
            {
                c = in.read();
                System.out.print((char) c);
            }
        }
        out.close();
        in.close();
        socket.close();
        System.exit(0);
    }
}

This gets stuck at STARTTLS and although I am encoding with base64 the user-name and pass-word but it remains stuck there. What wrong am I doing? Please, help me out. Thank you! PS: - I am new to Java.

I would suggest to rely on the inputStream::available() method for reading the content. In that way, you may create a helper method like

private static String readResponse(InputStream inputStream) throws IOException {
    int c;
    StringBuilder raw = new StringBuilder();
    do {
        c = inputStream.read();
        raw.append((char) c);
    } while (inputStream.available() > 0);
    return raw.toString();
}

Then replace code block

int c = '\0';
while (c != -1) {
    c = in.read();
    System.out.print((char) c);
}

on the System.out.println(readResponse(in)); .

In that way you would proceed to the STARTTLS command, but I'm not sure you should send it because own implementation of TLS using plain Sockets is not something you would like to do as a home task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM