Home > Blockchain >  Send emails with SMTP protocol using socket class - Java
Send emails with SMTP protocol using socket class - Java

Time:01-11

I'm trying to develop a class that sends email through the SMTP protocol but without using libraries that facilitate sending mail such as MimeMessage or MailUtility. This is what I've done so far:

public class MailSender {

    protected String localMachine;
    protected String localSMTPServer;
    private String textMail;

    private String mailFrom;

    public MailSender(String localSMTPServer, String mailFrom) {
        try {
            this.textMail = "null";

            this.localSMTPServer = localSMTPServer;

            this.mailFrom = mailFrom;

            InetAddress localIP = InetAddress.getLocalHost();

            this.localMachine = localIP.getHostAddress();

        } catch (UnknownHostException ex) {
            Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
     //getter and setter
    public void smtp(String command) {
        try {
            System.out.println(sIn.readLine());
             os.write((command   "\n").getBytes());
             System.out.println("end");
        } catch (IOException ex) {
            System.out.println(ex);
            Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
        }
       
    }
 BufferedReader sIn;
 OutputStream os;
    public Boolean trySend(String destUser, String subject, String message) {
        Socket socket;
        try {
            socket = new Socket(localSMTPServer, 587);

            OutputStreamWriter sOutW = new OutputStreamWriter(socket.getOutputStream(), "ASCII");

            PrintWriter sOut = new PrintWriter(sOutW, true);
            InputStreamReader sInR = new InputStreamReader(socket.getInputStream(), "ASCII");
            
            sIn = new BufferedReader(sInR);
            os = socket.getOutputStream();
            this.nextSMTPCode(sIn, 220);
            sOut.println("EHLO");
            this.nextSMTPCode(sIn, 250);
      
            sOut.println("AUTH LOGIN");
            this.nextSMTPCode(sIn, 250);
            
            sOut.println("xxxxxxxxxxxxxxx=="); //username 
            sOut.println("xxxxxxxxxxxxxx="); //password 
            this.nextSMTPCode(sIn, 250);
            
            sOut.println("MAIL FROM: <"   this.mailFrom   ">");
            this.nextSMTPCode(sIn, 250);
            sOut.println("RCPT TO: <"   destUser   ">");
            this.nextSMTPCode(sIn, 250);
            
            
            
            sOut.println("DATA");
            this.nextSMTPCode(sIn, 250);
            sOut.println("From: "   this.mailFrom);
            sOut.println("To: "   destUser);
            sOut.println("Subject: "   subject);
            sOut.println(message);
            
            sOut.println(".");
            this.nextSMTPCode(sIn, 250);
            
            sOut.println("QUIT");
            this.nextSMTPCode(sIn, 250);
            
            sIn.close();
            textMail = "From "   this.mailFrom   " To "   destUser   "\n"   "Subject: "   subject   "\nMessage: "   message;
            return true;
        } catch (IOException ex) {
            Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
        }

        return false;
    }

    public String getMail() {

        return textMail;
    }

    private void nextSMTPCode(BufferedReader sIn, int expectedCode) throws IOException {

        int code;
        String str = sIn.readLine();
        System.out.println(str);
        String sCode = str.substring(0, 3);
        code = Integer.parseInt(sCode);

        if (code != expectedCode) {

            sIn.close();
            System.out.println("Code: "   code   " expected code was: "   expectedCode);
            throw new IOException();
        }

    }

}

I am having problem with communication with smtp server, I am using smtp2go as smtp server. The problem is that I keep getting the 250 code even when this shouldn't show up, finally the email isn't sent. This is a sample communication:

220 mail.smtp2go.com 
ESMTP Exim 4.96-S2G Tue, 10 Jan 2023 14:42:02
 0000 250-mail.smtp2go.com Hello  [xxxxx] 
250-SIZE 52428800 
250-8BITMIME 
250-DSN 250-PIPELINING 
250-PIPECONNECT 
250-AUTH CRAM-MD5
PLAIN LOGIN 
250-CHUNKING

I then get 250-SIZE 52428800 and the other responses (always with the code 250) for every command I send. I tried to telnet and everything seems to work, the problem is in my code but I can't figure out what I'm doing wrong. Does anyone know the cause of this problem?

CodePudding user response:

SMTP can have multiline responses, but you only expect singleline responses. Multiline responses are typical for EHLO. To cite from RFC 5231:

The format for multiline replies requires that every line, except the last, begin with the reply code, followed immediately by a hyphen, "-" (also known as minus), followed by text. The last line will begin with the reply code, followed immediately by , optionally some text, and . As noted above, servers SHOULD send the if subsequent text is not sent, but clients MUST be prepared for it to be omitted.

For example:

 250-First line
 250-Second line
 250-234 Text beginning with numbers
 250 The last line
  • Related