Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 10 of 10

Thread: SMTP SERVER in Java

  1. #1
    Junior Member
    Join Date
    Feb 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default SMTP SERVER in Java

    Hello!

    I am doing a project for a class and have gotten completely stuck. We are creating an SMTP server using Java. The instructions are as followed:

    Implement commands HELO, MAIL, RCPT, DATA, QUIT in such a way so your SMTP server will be capable of treating sequence of incoming SMTP commands to compile a list of messages. Each message is to be presented as a member of some collection for later processing. The collection of messages can be associated with particular SMTP session (timestamp and/or IP:port of the client can be used for identification purposes) so collections of messages from different sessions will not affect each other.
    Optionally you can implement RSET command, which resets the ongoing session to the state where MAIL command is expected.
    Upon completion of an SMTP session, corresponding queue (collection) of messages must be dumped into a log file (plaintext format) for debuging purposes. Each message must be represented by all required components (sender, recipient(s), body). Messages must be separated by a single empty line. Incomplete messages must not be included in the log

    Im not sure where to even create the commands. Any help would be greatly appreciated! I have code already completed up to this point and can share if needed, just not sure how to write the above mentioned.

    Greatly appreciative!

    Scapres75


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,592
    Thanks
    50
    Thanked 2,235 Times in 2,207 Posts

    Default Re: SMTP SERVER in Java

    where to even create the commands
    Can you explain what that means?

    A server receives SMTP commands. What commands are you trying to create?
    How will you test the server?
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Junior Member
    Join Date
    Feb 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default SMTP Server Help! need to write commands for Helo, Mail, RCPT, Data and Quit

    I have 3 classes: FSM, ServerThread and smtpd. The code is posted below. My question is how do I Implement commands HELO, MAIL, RCPT, DATA, QUIT in such a way so SMTP server will be capable of treating sequence of incoming SMTP commands to compile a list of messages. I then need each message to be presented as a member of some collection for later processing. The collection of messages can be associated with particular SMTP session (timestamp and/or IP:port of the client can be used for identification purposes) so collections of messages from different sessions will not affect each other.
    Optionally I need to implement RSET command, which resets the ongoing session to the state where MAIL command is expected.
    Upon completion of an SMTP session, corresponding queue (collection) of messages must be dumped into a log file (plaintext format) for debuging purposes. Each message must be represented by all required components (sender, recipient(s), body). Messages must be separated by a single empty line. Incomplete messages must not be included in the log.

    Any ideas, suggestions or code would be greatly appreciated.

    First class

    import java.util.HashMap;

    enum smtpdStates {
    wfHELO,
    wfMAIL,
    wfRCPT,
    wfDATA,
    wfPeriod,
    wfRSET;

    };

    class mapData {
    private smtpdStates state;
    private String text;
    public mapData(smtpdStates state, String text) {
    super();
    this.state = state;
    this.text = text;
    }
    public static mapData of(smtpdStates state, String text) {
    return new mapData(state,text);
    }
    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((state == null) ? 0 : state.hashCode());
    result = prime * result + ((text == null) ? 0 : text.toLowerCase().hashCode());
    return result;
    }
    @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    mapData other = (mapData) obj;
    if (state != other.state)
    return false;
    if (text == null) {
    if (other.text != null)
    return false;
    } else if (!text.equalsIgnoreCase(other.text))
    return false;
    return true;
    }
    public String toString() {
    return this.text;
    }
    public smtpdStates getState() {
    return state;
    }
    public String getText() {
    return text;
    }
    }

    public class FSM {
    public static void main(String[] args) {
    HashMap<mapData,mapData> myMap = new HashMap<mapData,mapData>();
    myMap.put(new mapData(smtpdStates.wfHELO,"helo"),new mapData(smtpdStates.wfMAIL,"250 OK"));
    myMap.put(mapData.of(smtpdStates.wfHELO,"help"),ma pData.of(smtpdStates.wfHELO,"Help message"));
    myMap.put(mapData.of(smtpdStates.wfMAIL,"mail"),ma pData.of(smtpdStates.wfRCPT,"250 OK RCPT received"));
    myMap.put(mapData.of(smtpdStates.wfRSET,"mail"),ma pData.of(smtpdStates.wfRCPT,"Seesion has been reset"));
    System.out.println(myMap.get(mapData.of(smtpdState s.wfMAIL, "MaIl")));
    }
    }

    SECOND CLASS

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.HashMap;

    public class ServerThread extends Thread {
    private BufferedReader br;
    private PrintWriter pw;;
    private Socket client;
    private HashMap FSM;
    private boolean TerminationFlag;

    public boolean isTerminationFlag() {
    return TerminationFlag;
    }
    private String help() {
    return "This is a help message";
    }
    public ServerThread(Socket client, HashMap FSM) {
    this.client = client;
    this.FSM = FSM;
    this.TerminationFlag = false;
    }
    public void run() {
    String temp = null;
    smtpdStates s = smtpdStates.wfHELO;
    try {
    br = new BufferedReader(new InputStreamReader(client.getInputStream()));
    pw = new PrintWriter(client.getOutputStream(),true);
    }
    catch (IOException e) {
    System.err.println("I/O stream cannot be extracted");
    //-- to add additional processing
    }
    while(true) {
    try {
    temp = br.readLine();
    }
    catch (IOException e) {
    System.err.println("Readline() failed");
    //-- to add additional processing
    }

    if(temp.equalsIgnoreCase("help")) {
    pw.println(help());
    continue;
    }
    else if(temp.equalsIgnoreCase("quit")) {
    try {
    pw.println("250 OK. Bye-bye");
    br.close();
    pw.close();
    client.close();
    }
    catch (IOException e) {
    System.err.println("Clean up procedure failed");
    //-- to add additional processing
    }
    this.TerminationFlag = true;
    break;
    }
    String cmd = temp.split(" ",2)[0];

    System.out.println("Was in state: " + s + "'");
    System.out.println("Received: '" + cmd + "'");

    mapData fsmResponse = (mapData)FSM.get(mapData.of(s,cmd));
    if(fsmResponse == null) {
    pw.println("Command cannot be recognized");
    continue;
    }
    s = fsmResponse.getState();
    System.out.println("New state: '" + s + "'");
    System.out.println("Response: '" + fsmResponse.getText() + "'\n");

    pw.println(fsmResponse.getText());
    }
    }
    }

    THIRD CLASS

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketException;
    import java.util.ArrayList;
    import java.util.HashMap;

    public class smtpd {

    public static void main(String[] args) {
    int port = 0;
    ArrayList<ServerThread> listOfThreads = new ArrayList<ServerThread>();

    HashMap<mapData,mapData> myMap = new HashMap<mapData,mapData>();
    myMap.put(new mapData(smtpdStates.wfHELO,"helo"),new mapData(smtpdStates.wfMAIL,"250 OK"));
    myMap.put(new mapData(smtpdStates.wfHELO,"mail"),new mapData(smtpdStates.wfMAIL,"777 Received MAIL, but expected HELO"));
    myMap.put(new mapData(smtpdStates.wfHELO,"rcpt"),new mapData(smtpdStates.wfMAIL,"777 Received RCPT, but expected HELO"));
    myMap.put(new mapData(smtpdStates.wfHELO,"data"),new mapData(smtpdStates.wfMAIL,"777 Received DATA, but expected HELO"));

    myMap.put(mapData.of(smtpdStates.wfMAIL,"helo"),ma pData.of(smtpdStates.wfRCPT,"250 OK RCPT received"));
    myMap.put(mapData.of(smtpdStates.wfMAIL,"mail"),ma pData.of(smtpdStates.wfRCPT,"250 OK RCPT received"));
    myMap.put(new mapData(smtpdStates.wfMAIL,"rcpt"),new mapData(smtpdStates.wfRCPT,"777 Received RCPT, but expected HELO"));
    myMap.put(new mapData(smtpdStates.wfMAIL,"data"),new mapData(smtpdStates.wfRCPT,"777 Received DATA, but expected HELO"));

    myMap.put(mapData.of(smtpdStates.wfRCPT,"helo"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfRCPT,"mail"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfRCPT,"rcpt"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfRCPT,"data"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));

    myMap.put(mapData.of(smtpdStates.wfDATA,"helo"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfDATA,"mail"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfDATA,"rcpt"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));
    myMap.put(mapData.of(smtpdStates.wfDATA,"data"),ma pData.of(smtpdStates.wfRCPT,"888 Waiting for RCPT"));

    myMap.put(mapData.of(smtpdStates.wfRSET,"mail"),ma pData.of(smtpdStates.wfRCPT,"Seesion has been reset"));
    myMap.put(mapData.of(smtpdStates.wfRSET,"helo"),ma pData.of(smtpdStates.wfRCPT,"Seesion has been reset"));
    myMap.put(mapData.of(smtpdStates.wfRSET,"rcpt"),ma pData.of(smtpdStates.wfRCPT,"Seesion has been reset"));
    myMap.put(mapData.of(smtpdStates.wfRSET,"data"),ma pData.of(smtpdStates.wfRCPT,"Seesion has been reset"));

    if(args.length < 1) {
    System.err.println("Need at least on command line argument");
    System.exit(1);
    }
    try {
    port = Integer.parseInt(args[0]);
    }
    catch(NumberFormatException ex) {
    System.err.println("First command-line argument must be an integer");
    System.exit(2);
    }
    ServerSocket server;
    Socket client;
    while(true) {
    try {
    server = new ServerSocket(port);
    break;
    }
    catch (IOException e) {
    port++;
    }
    }
    System.out.println("Port number is " + port);
    try {
    server.setSoTimeout(5000);
    }
    catch (SocketException e) {
    System.err.println("ServerSocket timeout setting failed: " + e);
    }
    while(true) {
    try {
    client = server.accept();
    //-- create new thread to serve new connection request
    System.out.println("New client from '" + client.getRemoteSocketAddress() + "' requested connection");
    ServerThread tempThread = new ServerThread(client,myMap);
    listOfThreads.add(tempThread);
    tempThread.start();
    }
    catch (java.net.SocketTimeoutException e1) {
    /*
    for(ServerThread T : listOfThreads) {
    //-- Try this approach to implement iteration, it should throw an exception
    }
    */
    for(int i=listOfThreads.size()-1; i>= 0; i--) {
    ServerThread termThread = listOfThreads.get(i);
    if(termThread.isTerminationFlag() == true) {
    try {
    termThread.join();
    }
    catch (InterruptedException e2) {
    System.err.println("Joining of a thread failed: " + e2);
    }
    listOfThreads.remove(termThread);
    System.out.println("Thread had been successfully removed.");
    }
    }
    }
    catch (IOException e3) {
    System.err.println("Accept() method returned error: " + e3);
    //-- to add additional processing
    }
    }

    }
    }

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,592
    Thanks
    50
    Thanked 2,235 Times in 2,207 Posts

    Default Re: SMTP Server Help! need to write commands for Helo, Mail, RCPT, Data and Quit

    Please edit your post and wrap your code with code tags:
    [code=java]
    YOUR CODE HERE
    [/code]
    to get highlighting and preserve formatting.

    Is this the same topic: SMTP SERVER in Java
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Junior Member
    Join Date
    Feb 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: SMTP SERVER in Java

    I need to create 4 commands in Java: The HELO command, MAIL command, RCPT command and the DATA command. I will test the server using telnet localhost. The code attached works for the Help and Quit commands, but the above mentioned I am not familiar with.

  6. #6
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,592
    Thanks
    50
    Thanked 2,235 Times in 2,207 Posts

    Default Re: SMTP SERVER in Java

    What does the RFC doc for SMTP say the server needs to do for each of those commands?
    If you don't understand my answer, don't ignore it, ask a question.

  7. #7
    Junior Member
    Join Date
    Feb 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: SMTP SERVER in Java

    I apologize, I have the first part of my code, and those commands just need to added to it...would be glad to share!

    --- Update ---

    During one SMTP session a set of messages can be transferred from client to server. Each message in that set is supposed to have one sender (identified from MAIL command), one or several recipients (identified from RCPT command) and message body (identified from DATA command). All these pieces of information need to be stored in some way and I propose to introduce a message class at this point. Such class is expected to have several private data fields with a set of getters/setters methods. All messages received during one SMTP session are about to be stored individually as members of some collection, e.g. ArrayList<Message> . The collection is to be cleared up at the start of the SMTP session, and is expected to have 0 or more messages at the end of the SMTP session. The sequence of received SMTP commands must be treated towards populating this collection when new messages arrive.

  8. #8
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,592
    Thanks
    50
    Thanked 2,235 Times in 2,207 Posts

    Default Re: SMTP SERVER in Java

    Can you explain what problems you are having adding those commands to the server? What is the server supposed to do when it gets them?
    If you don't understand my answer, don't ignore it, ask a question.

  9. #9
    Junior Member
    Join Date
    Feb 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: SMTP Server Help! need to write commands for Helo, Mail, RCPT, Data and Quit

    Yes, but I am new to the forum and wasn't sure if I posted correctly

    --- Update ---

    I wasn't sure the correct "syntax" for posting code in the forum. Can you explain what you are referring too?
    Thanks
    scapres

  10. #10
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,592
    Thanks
    50
    Thanked 2,235 Times in 2,207 Posts

    Default Re: SMTP SERVER in Java

    Threads merged.
    If you don't understand my answer, don't ignore it, ask a question.

Similar Threads

  1. Muliple Client Server chat application..how to send message from server..
    By jesroni in forum What's Wrong With My Code?
    Replies: 3
    Last Post: September 14th, 2013, 11:17 PM
  2. DEBUG SMTP: could not connect to host "host.domain.uk", port: 25, response: 421
    By aueddonline in forum What's Wrong With My Code?
    Replies: 0
    Last Post: August 21st, 2012, 04:47 AM
  3. Receive Server Sent Event Notifications in JAVA SERVER PAGE (JSP)
    By amritasenthilkumar in forum Web Frameworks
    Replies: 1
    Last Post: August 17th, 2012, 02:30 PM
  4. java GMAIL smtp with attach
    By Jhovarie in forum File I/O & Other I/O Streams
    Replies: 3
    Last Post: October 10th, 2011, 10:11 AM

Tags for this Thread