Java Network Programming UsingSmtp – Report/Overview.

Authors Avatar

Network Protocols and Implementation        

                20/03/04

JAVA NETWORK PROGRAMMING USING SMTP – REPORT/OVERVIEW

SMTP’s main objective is to transfer mail both efficiently and reliably.  This method is individual and requires only a data stream channel.

All networks are likely to have an SMTP gateway, which allows any user on the network to communicate with other users, without having to worry about which local mail software packages are existing on the network.  Through this gateway, mail coming through the network, will automatically be converted into the appropriate format to the local mail software.  DNS queries/translations, however, cannot be implemented through SMTP gateways, for this function we need to use an SMTP relay.

SMTP works quite simply in the following way;

  • The user composes and sends a message in a client application
  • The application issues a request to the server to send the message
  • The server examines the recipient address information in the message
  • The server determines the location of the destination server and initiates contact using the common protocol
  • The contacted server is asked to affirm that it is the destination server
  • If the replies are affirmative, information about the message is passed, and requests to pass the message are made
  • The destination server then gives permission and the message is passed, verified and contact is terminated

Figure displaying SMTP model

SMTP is basically based on an end-to-end delivery, so the connection from SMTP client to SMTP server is a direct connection.  Using a mail gateway for sending mail, SMTP cant route directly to the recipients host, so a different approach is taken which is where SMTP sends the mail from; host to gateway, gateway to gateway, gateway to host.  This basically means that for mail transmission beyond the TCP/IP network to the destination host, SMTP is not defined.

The DNS information within the java application using SMTP is organised into lines of information called resource records (RR), each having different meanings and purposes.  The MX (Mail eXchanger) is what records the name and prioritises the mail servers that are accepting mail for a domain.

Even though the SMTP protocol is well set, there can be a few errors.  For example; the message length can cause problems.  In some situations where the messages are exceeding 64kb, for example cannot be handled by the SMTP protocol.  Timeouts can also cause a problem.  If there are different timeouts for each of the client and the server, then one could give up while the other one is still busy; terminating the connection without warning.  Extended SMTP or ESMTP was created to get around this problem.

Implementation of the client application

import java.awt.*;

import java.io.*;

import java.net.*;

import java.util.*;

class SMTPInputStream

{

        private InputStream is=null;

        SMTPInputStream(Socket s) throws IOException

        {

                is = s.getInputStream();

        }

        String ReadFromStream()         throws IOException

        {

                String s=new String("");

                while ((is.available()>0) && (s.length()<255))

                        s=s+String.valueOf((char) is.read());

                return s;

        }

    void Close() throws IOException

        {

                is.close();

                is=null;

    }

}

class SMTPOutputStream

{

        private OutputStream os=null;

        SMTPOutputStream(Socket s) throws IOException

        {

            os=s.getOutputStream();

        }

        void WriteToStream(String s) throws IOException

        {

                if (s.length()>0)

                {

                        for (int i=0;(i<s.length());i++)

                         os.write((int) s.charAt(i));

                }

        }

    void Close() throws IOException

        {

                os.close();

                os=null;

        }

}

public class SMTPprotocol extends Frame

    {

//******************************************************************

//RFC 821 Standarts

//SMTP Commands

        final String[] SMTPCommand =

        {

                "HELO",

                "MAIL FROM:",

                "RCPT TO:",

                "DATA",

                "QUIT",

                "NOOP",

                "TURN",

                "RSET",

                "VRFY",

                "EXPN",

                "SEND FROM:",

                "SOML FROM:",

                "SAML FROM:",

                "\r\n.\r\n",

                "\r\n",

                " "

        };

//Command codes here

        final int SMTP_CMD_HELO=0;

        final int SMTP_CMD_MAIL_FROM=1;

        final int SMTP_CMD_RCPT_TO=2;

        final int SMTP_CMD_DATA=3;

        final int SMTP_CMD_QUIT=4;

        final int SMTP_CMD_NOOP=5;

        final int SMTP_CMD_TURN=6;

        final int SMTP_CMD_RSET=7;

        final int SMTP_CMD_VRFY=8;

        final int SMTP_CMD_EXPN=9;

        final int SMTP_CMD_SEND_FROM=10;

        final int SMTP_CMD_SOML_FROM=11;

        final int SMTP_CMD_SAML_FROM=12;

        final int SMTP_CMD_CRLF_CRLF=13;

        final int SMTP_CMD_CRLF=14;

        final int SMTP_CMD_SPC=15;

        

//read data from input stream to globalBuffer String

//return true if ok

//false if timeout

String globalBuffer=new String("");

int waitForTimeout(SMTPInputStream i) throws IOException

{

        boolean defStatus;

        long startTime;

        int replyCode;

//WAIT FOR RESPONSE (WAIT_TIMEOUT) millis

        startTime=System.currentTimeMillis();

        while ((System.currentTimeMillis()-startTime)<WAIT_TIMEOUT)

        {

           globalBuffer="";

           globalBuffer=i.ReadFromStream();

           if (globalBuffer.length()>0)

           {

                 try

                 {

 replyCode=Integer.valueOf(globalBuffer.substring(0,3)).intValue();

 infoArea.Println("SERVER RESPONSE: "+globalBuffer);

                      return replyCode;

                 }

                 catch(NumberFormatException e)

         {

                          return -1;

                 }

           }

        }

        return 0;

}

int doSMTPTransaction(SMTPInputStream in,SMTPOutputStream out) throws

IOException

{

    int replyCode;

        Date today=new Date();

//GET SERVER RESPONSE on CONNECTION ESTABLISHMENT

//WAIT FOR RESPONSE (WAIT_TIMEOUT) millis

//        NOT RESPONSE ON CONNECT ERROR CODE 1

        replyCode=waitForTimeout(in);

        if (replyCode==0)

        {

            infoArea.Println("NOT RESPONSE ON CONNECT ERROR CODE 1");

                return 1;

        }

        if (replyCode==-1)

        {

            infoArea.Println("UNKNOWN REPLY CODE ERROR CODE 4");

                return 4;

        }

        if (replyCode!=SMTP_RCODE_READY)

        {

            infoArea.Println("UNSUCCESS CONNECTION ");

                return replyCode;

        }

        infoArea.Println("connection response is OK");

        infoArea.Println("request HELO");

//SEND HELO CRLF

        out.WriteToStream(SMTPCommand[SMTP_CMD_HELO]);

        out.WriteToStream(SMTPCommand[SMTP_CMD_SPC]);

        out.WriteToStream("127.0.0.1");

        out.WriteToStream(SMTPCommand[SMTP_CMD_CRLF]);

//WAIT FOR RESPONSE ON HELO

        replyCode=waitForTimeout(in);

        if (replyCode==0)

        {

            infoArea.Println("NOT RESPONSE TO HELO ERROR CODE 2");

                return 2;

        }

        if (replyCode==-1)

        {

            infoArea.Println("UNKNOWN REPLY CODE ERROR CODE 4");

                return 4;

        }

        if (replyCode!=SMTP_RCODE_COMPLETED)

        {

            infoArea.Println("UNABLE TO COMPLETE REPLY");

Join now!

                return replyCode;

        }

        infoArea.Println("HELO response is OK");

        infoArea.Println("request MAIL FROM");

   

        //SEND MAIL FROM: SPC <sender> CRLF

        out.WriteToStream(SMTPCommand[SMTP_CMD_MAIL_FROM]);

        out.WriteToStream(SMTPCommand[SMTP_CMD_SPC]);

        out.WriteToStream(senderMail.getText());

        out.WriteToStream(SMTPCommand[SMTP_CMD_CRLF]);

//WAIT FOR RESPONSE ON MAIL FROM

        replyCode=waitForTimeout(in);

        if (replyCode==0)

        {

            infoArea.Println("NOT RESPONSE TO HELO ERROR CODE 2");

                return 2;

        }

        if (replyCode==-1)

        {

            infoArea.Println("UNKNOWN REPLY CODE ERROR CODE 4");

                return 4;

        }

        if (replyCode!=SMTP_RCODE_COMPLETED)

        {

            infoArea.Println("UNABLE TO COMPLETE REPLY");

                return replyCode;

        }

        infoArea.Println("MAIL FROM response is OK");

        infoArea.Println("request RCPT TO");

   

        //SEND RCPT TO: SPC <sender> CRLF

        out.WriteToStream(SMTPCommand[SMTP_CMD_RCPT_TO]);

        out.WriteToStream(SMTPCommand[SMTP_CMD_SPC]);

        out.WriteToStream(reciverMail.getText());

        out.WriteToStream(SMTPCommand[SMTP_CMD_CRLF]);

//WAIT FOR RESPONSE ON RCPT TO

...

This is a preview of the whole essay