Mega Code Archive

 
Categories / Java / Swing Components
 

A Client to Send SMTP Mail

import java.awt.*; import javax.swing.*; /**  * Example program from Chapter 1 Programming Spiders, Bots and Aggregators in  * Java Copyright 2001 by Jeff Heaton  *   * SendMail is an example of client sockets. This program presents a simple  * dialog box that prompts the user for information about how to send a mail.  *   * @author Jeff Heaton  * @version 1.0  */ /*  * Using the SMTP Program  *   * To use the program in Listing 1.2, you must know the address of an SMTP  * server usually provided by your ISP. If you are unsure of your SMTP server,  * you should contact your ISP's customer service. In order for outbound e-mail  * messages to be sent, your e-mail program must have this address. Once it  * does, you can enter who is sending the e-mail (if you are sending it, you  * would type your e-mail address in) and who will be on the receiving end. This  * is usually entered under the Reply To field of your e-mail program. Both of  * these addresses must be valid. If they are invalid, the e-mail may not be  * sent. After you have entered these addresses, you should continue by entering  * the subject, writing the actual message, and then clicking send. Note  *   * For more information on how to compile examples in this book, see Appendix E  * 'How to Compile Examples Under Windows.'  *   * As stated earlier, to send an e-mail with this program, you must enter who is  * sending the message. You may be thinking that you could enter any e-mail  * address you want here, right? Yes, this is true; as long as the SMTP server  * allows it, this program will allow you to impersonate anyone you enter into  * the To address field. However, as previously stated, a savvy Internet user  * can tell whether the e-mail address is fake.  *   * After the mention of possible misrepresentation of identity on the sender's  * end, you may now be asking yourself, Is this program dangerous? This  * program is no more dangerous than any e-mail client (such as Microsoft  * Outlook Express or Eudora) that also requires you to tell it who you are. In  * general, all e-mail programs must request both your identity and that of the  * SMTP server. Examining the SMTP Server  *   * You will now be shown how this program works. We will begin by looking at how  * a client socket is created. When the client socket is first instantiated, you  * must specify two parameters. First, you must specify the host to connect to;  * second, you must specify the port number (e.g., 80) you would like to connect  * on. These two items are generally passed into the constructor. The following  * line of code (from Listing 1.2) accomplishes this:  *   * java.net.Socket s =new java.net.Socket( _smtp.getText(),25 );  *   * This line of code creates a new socket, named s. The first parameter to the  * constructor, _smtp .getText(), specifies the address to connect to. Here it  * is being read directly from a text field. The second parameter specifies the  * port to connect to. (The port for SMTP is 25.) Table 1.1 shows a listing of  * the ports associated with most Internet services. The hostname is retrieved  * from the _smtp class level variable, which is the JTextField control that the  * SMTP hostname is entered into.  *   * If any errors occur while you are making the connection to the specified  * host, the Socket constructor will throw an IOException. Once this connection  * is made, input and output streams are obtained from the Socket.getInputStream  * and Socket.getOutputStream methods. This is done with the following lines of  * code from Listing 1.2:  *   * _out = new java.io.PrintWriter(s.getOutputStream());  * _in = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream()));  *   * These low-level stream types are only capable of reading binary data. Because  * this data is needed in text format, filters are used to wrap the lower-level  * input and output streams obtained from the socket.  *   * In the code above, the output stream has been wrapped in a PrintWriter  * object. This is because PrintWriter allows the program to output text to the  * socket in a similar manner to the way an application would write data to the  * System.out object by using the print and println methods. The application  * presented here uses the println method to send commands to the SMTP server.  * As you can see in the code, the InputStream object has also been wrapped; in  * this case, it has been wrapped in a BufferedReader. Before this could happen,  * however, this object must first have been wrapped in an InputStreamReader  * object as shown here:  *   * _in = new java.io.BufferedReader(new  * java.io.InputStreamReader(s.getInputStream()));  *   * This is done because the BufferedReader object provides reads that are made  * up of lines of text instead of individual bytes. This way, the program can  * read text up to a carriage return without having to parse the individual  * characters. This is done with the readLine method.  *   * You will now be shown how each command is sent to the SMTP server. Each of  * these commands that is sent results in a response being issued from the SMTP  * server. For the protocol to work correctly, each response must be read by the  * SMTP client program. These responses start with a number and then they give a  * textual description of what the result was. A full-featured SMTP client  * should examine these codes and ensure that no error has occurred.  *   * For the purposes of the SendMail example, we will simple ignore these  * responses because most are informational and not needed. Instead, for our  * purposes, the response will be read in and displayed to the _output list box.  * Commands that have been sent to the server are displayed in this list with a  * C: prefix to indicate that they are from the client. Responses returned from  * the SMTP server will be displayed with the S: prefix.  *   * To accomplish this, the example program will use the send method. The send  * method accepts a single String parameter to indicate the SMTP command to be  * issued. Once this command is sent, the send method awaits a response from the  * SMTP host. The portion of Listing 1.2 that contains the send method is  * displayed here:  *   * protected void send(String s) throws java.io.IOException {          // Send the SMTP command           if(s!=null) {           _model.addElement("C:"+s);           _out.println(s);         _out.flush(); }         // Wait for the response           String line = _in.readLine();         if(line!=null) {         _model.addElement("S:"+line);         }   }  *   * As you can see, the send method does not handle the exceptions that might  * occur from its commands. Instead, they are thrown to the calling method as  * indicated by the throws clause of the function declaration. The variable s is  * checked to see if it is null. If s is null, then no command is to be sent and  * only a response is sought. If s is not null, then the value of s is logged  * and then sent to the socket. After this happens, the flush command is given  * to the socket to ensure that the command was actually sent and not just  * buffered. Once the command is sent, the readLine method is called to await  * the response from the server. If a response is sent, then it is logged.  *   * Once the socket is created and the input and output objects are created, the  * SMTP session can begin. The following commands manage the entire SMTP  * session:  *   * send(null);   * send("HELO " + java.net.InetAddress.getLocalHost().getHostName() );  * send("MAIL FROM: " + _from.getText() ); send("RCPT TO: " + _to.getText() );  * send("DATA");   * _out.println("Subject:" + _subject.getText()); _out.println(  * _body.getText() ); send("."); s.close();  *   * Tip  *   * Refer to Table 1.4 in the preceding section to review the details of what  * each of the SMTP commands actually means.  *   * The rest of the SendMail program (as seen in Listing 1.2) is a typical Swing  * application. The graphical user interface (GUI) layout for this application  * was created using VisualCaf?. The VisualCaf? comments have been left in to  * allow the form's GUI layout to be edited by VisualCaf? if you are using it.  * If you are using an environment other than VisualCaf?, you may safely delete  * the VisualCaf? comments (lines starting in //). The VisualCaf? code only  * consists of comments and does not need to be deleted to run on other  * platforms.  *    */ public class SendMail extends javax.swing.JFrame {   /**    * The constructor. Do all basic setup for this application.    */   public SendMail() {     //{{INIT_CONTROLS     setTitle("SendMail Example");     getContentPane().setLayout(null);     setSize(736, 312);     setVisible(false);     JLabel1.setText("From:");     getContentPane().add(JLabel1);     JLabel1.setBounds(12, 12, 36, 12);     JLabel2.setText("To:");     getContentPane().add(JLabel2);     JLabel2.setBounds(12, 48, 36, 12);     JLabel3.setText("Subject:");     getContentPane().add(JLabel3);     JLabel3.setBounds(12, 84, 48, 12);     JLabel4.setText("SMTP Server:");     getContentPane().add(JLabel4);     JLabel4.setBounds(12, 120, 84, 12);     getContentPane().add(_from);     _from.setBounds(96, 12, 300, 24);     getContentPane().add(_to);     _to.setBounds(96, 48, 300, 24);     getContentPane().add(_subject);     _subject.setBounds(96, 84, 300, 24);     getContentPane().add(_smtp);     _smtp.setBounds(96, 120, 300, 24);     getContentPane().add(_scrollPane2);     _scrollPane2.setBounds(12, 156, 384, 108);     _body.setText("Enter your message here.");     _scrollPane2.getViewport().add(_body);     _body.setBounds(0, 0, 381, 105);     Send.setText("Send");     Send.setActionCommand("Send");     getContentPane().add(Send);     Send.setBounds(60, 276, 132, 24);     Cancel.setText("Cancel");     Cancel.setActionCommand("Cancel");     getContentPane().add(Cancel);     Cancel.setBounds(216, 276, 120, 24);     getContentPane().add(_scrollPane);     _scrollPane.setBounds(408, 12, 312, 288);     getContentPane().add(_output);     _output.setBounds(408, 12, 309, 285);     //}}     //{{INIT_MENUS     //}}     //{{REGISTER_LISTENERS     SymAction lSymAction = new SymAction();     Send.addActionListener(lSymAction);     Cancel.addActionListener(lSymAction);     //}}     _output.setModel(_model);     _model.addElement("Server output displayed here:");     _scrollPane.getViewport().setView(_output);     _scrollPane2.getViewport().setView(_body);   }   /**    * Moves the app to the correct position when it is made visible.    *     * @param b    *            True to make visible, false to make invisible.    */   public void setVisible(boolean b) {     if (b)       setLocation(50, 50);     super.setVisible(b);   }   /**    * The main function basically just creates a new object, then shows it.    *     * @param args    *            Command line arguments. Not used in this application.    */   static public void main(String args[]) {     (new SendMail()).show();   }   /**    * Created by VisualCafe. Sets the window size.    */   public void addNotify() {     // Record the size of the window prior to     // calling parents addNotify.     Dimension size = getSize();     super.addNotify();     if (frameSizeAdjusted)       return;     frameSizeAdjusted = true;     // Adjust size of frame according to the     // insets and menu bar     Insets insets = getInsets();     javax.swing.JMenuBar menuBar = getRootPane().getJMenuBar();     int menuBarHeight = 0;     if (menuBar != null)       menuBarHeight = menuBar.getPreferredSize().height;     setSize(insets.left + insets.right + size.width, insets.top         + insets.bottom + size.height + menuBarHeight);   }   // Used by addNotify   boolean frameSizeAdjusted = false;   //{{DECLARE_CONTROLS   /**    * A label.    */   javax.swing.JLabel JLabel1 = new javax.swing.JLabel();   /**    * A label.    */   javax.swing.JLabel JLabel2 = new javax.swing.JLabel();   /**    * A label.    */   javax.swing.JLabel JLabel3 = new javax.swing.JLabel();   /**    * A label.    */   javax.swing.JLabel JLabel4 = new javax.swing.JLabel();   /**    * Who this message is from.    */   javax.swing.JTextField _from = new javax.swing.JTextField();   /**    * Who this message is to.    */   javax.swing.JTextField _to = new javax.swing.JTextField();   /**    * The subject of this message.    */   javax.swing.JTextField _subject = new javax.swing.JTextField();   /**    * The SMTP server to use to send this message.    */   javax.swing.JTextField _smtp = new javax.swing.JTextField();   /**    * A scroll pane.    */   javax.swing.JScrollPane _scrollPane2 = new javax.swing.JScrollPane();   /**    * The body of this email message.    */   javax.swing.JTextArea _body = new javax.swing.JTextArea();   /**    * The send button.    */   javax.swing.JButton Send = new javax.swing.JButton();   /**    * The cancel button.    */   javax.swing.JButton Cancel = new javax.swing.JButton();   /**    * A scroll pain.    */   javax.swing.JScrollPane _scrollPane = new javax.swing.JScrollPane();   /**    * The output area. Server messages are displayed here.    */   javax.swing.JList _output = new javax.swing.JList();   //}}   /**    * The list of items added to the output list box.    */   javax.swing.DefaultListModel _model = new javax.swing.DefaultListModel();   /**    * Input from the socket.    */   java.io.BufferedReader _in;   /**    * Output to the socket.    */   java.io.PrintWriter _out;   //{{DECLARE_MENUS   //}}   /**    * Internal class created by VisualCafe to route the events to the correct    * functions.    *     * @author VisualCafe    * @version 1.0    */   class SymAction implements java.awt.event.ActionListener {     /**      * Route the event to the correction method.      *       * @param event      *            The event.      */     public void actionPerformed(java.awt.event.ActionEvent event) {       Object object = event.getSource();       if (object == Send)         Send_actionPerformed(event);       else if (object == Cancel)         Cancel_actionPerformed(event);     }   }   /**    * Called to actually send a string of text to the socket. This method makes    * note of the text sent and the response in the JList output box. Pass a    * null value to simply wait for a response.    *     * @param s    *            A string to be sent to the socket. null to just wait for a    *            response.    * @exception java.io.IOException    */   protected void send(String s) throws java.io.IOException {     // Send the SMTP command     if (s != null) {       _model.addElement("C:" + s);       _out.println(s);       _out.flush();     }     // Wait for the response     String line = _in.readLine();     if (line != null) {       _model.addElement("S:" + line);     }   }   /**    * Called when the send button is clicked. Actually sends the mail message.    *     * @param event    *            The event.    */   void Send_actionPerformed(java.awt.event.ActionEvent event) {     try {       java.net.Socket s = new java.net.Socket(_smtp.getText(), 25);       _out = new java.io.PrintWriter(s.getOutputStream());       _in = new java.io.BufferedReader(new java.io.InputStreamReader(s           .getInputStream()));       send(null);       send("HELO " + java.net.InetAddress.getLocalHost().getHostName());       send("MAIL FROM: " + _from.getText());       send("RCPT TO: " + _to.getText());       send("DATA");       _out.println("Subject:" + _subject.getText());       _out.println(_body.getText());       send(".");       s.close();     } catch (Exception e) {       _model.addElement("Error: " + e);     }   }   /**    * Called when cancel is clicked. End the application.    *     * @param event    *            The event.    */   void Cancel_actionPerformed(java.awt.event.ActionEvent event) {     System.exit(0);   } }