Function-Oriented Java

Http and Socket functions

Sending an Email
TestSocket
Get FileS Server Service
Send File By FTP
Get File using FTP
Get Anonymous FTP File
Send Telnet Command
Get RSS News Feed List
Get RSS News Feed Story
Get Proxy Server
Multiplexed HttpFileServer
Get NIO Proxy Server

Sending an Email

Email notification from within an application has become a popular mechanism for logging and other types of notification. As long as a network and a mail server are available, the application can send reports to an admin's e-mail inbox in a relatively straightforward manner.

Many Java users become familiar with the JavaMail API, an optional Java platform package that is also shipped as part of J2EE. It is intended to be a very robust API that can handle a number of different protocols and features robust security capability.

However, if you are sending simple text messages that do not require either advanced security or any advanced protocol, you really have to wonder why a protocol called Simple Mail Transfer Protocol (SMTP) requires any unusual voodoo to get you going. Most e-mail systems around the world use it and it is a protocol that has been around for a long time. It was originally defined in 1982 in an RFC by Jonathon Postel. SMTP defined a number of text-based verbs like MAIL, RECIPIENT, HELO, DATA, QUIT that could be used by the receiving server. The DATA section contains a number of fields, like "To:", "From:" , "CC:" and so on, just like the header you see at the top of your e-mail display.

For this reason, we build a very elementary function defined in sendEmail2() which sends a text message through a Socket connection. The function is a little more wordy than our alternate function, but it really shows you the true workings of the SMTP protocol. A socket is opened to the mail host on the default port (25), a "HELO" is sent, which is normally as a greeting from the sending domain. An RCPT section identifies recipients and a DATA section comprises the fields that you will see in the email body, starting with a TO:, FROM:, SUBJECT: and followed by a bunch of text. When the text is complete, a line with a single "." and another with a QUIT command complete the missive.

How to call the Function

NetworkFunctions.sendEmail2("mail.mchsi.com", //mailhost
			"gervasegallant@yahoo.com", //mailTo
			"gervase@javazoid.com",//mailFrom
			"","", //cc and bcc field
			"Hello!", //subject
			"Nel mezzo del camino della nostra vita..."); //and the message

Function code

After opening a socket to the mail host on port 25, we proceed to issue an "HELO", send some header data and complete the "DATA" section. Each field is delimited with a carriage return and linefeed, which is provided in the PrintWriter's println method. If a PrintWriter isn't used, you need to make sure a "\r\n" sequence is passed. The message ends with a "QUIT" and we check the socket's input stream for an "OK". Some mail servers do not return the OK.

public static void sendEmail2(String mailhost, String mailTo, 
			      String mailFrom, String cc, String bcc, 
			      String subject, String text)
				throws IOException{
		
	final int DEFAULT_PORT=25;
		
		
	Socket socket = new Socket(mailhost, DEFAULT_PORT);
	PrintWriter writer = new PrintWriter(socket.getOutputStream());
	DataInputStream dis = new DataInputStream(socket.getInputStream());
	String reply;
		            
	writer.println("HELO");
    	writer.println("MAIL From: " + mailFrom );
        writer.println("RCPT To: " + mailTo );
    	
    	if (cc != null && cc.indexOf("a") > -1)
    		writer.println("RCPT Cc:" + cc );

              
    	// Now send header and msg.        
    	writer.println("DATA");
                  
    	writer.println("X-Mailer: JavaFunctions using a Socket");
    	writer.println("DATE: " + new Date());
    	writer.println("From: " + mailFrom );
    	writer.println("To: " + mailTo );
               
    	if (cc != null && cc.indexOf("@") > -1)
    		writer.println("Cc: " + cc );
                
    	if (bcc != null && bcc.indexOf("@") > -1)
    		writer.println("RCPT Bcc: " + bcc );
    	
       	

    	writer.println("Subject: " + subject);
		writer.println(text )   ;	
    	writer.println("\r\n.");
    	writer.println("QUIT");
    	writer.flush();
                
    	//check response....    	
    	while((reply = dis.readLine())!=null){  
        	if(reply.indexOf("Ok") != -1){
            	System.out.println("SENT received OK");
            	break;
        	}
    	}
    	writer.close();
    	dis.close();
    	

	}

An alternate function -- sendEmail -- provides the same functionality, but with fewer lines of code. sendEmail() uses a URL and URLConnection to open a connection to the mailhost. Unlike the socket version, you must ensure that the "mailto" protocol is identified in the string constructor of URL. All the details of the SMTP RFC are hidden, so that you need only provide the common fields.

Calling the function

NetworkFunctions.sendEmail("mail.mchsi.com","gervasegallant@yahoo.com",
		"gervase@javazoid.com","","","Hello!",
		"I sent this using a URLConnection."); 
It has an identical parameter structure to the Socket version.

Function Code

public static void sendEmail(String mailhost, String mailTo, String mailFrom, String cc, String bcc, 
			String subject, String text)
			throws MalformedURLException, IOException{
		
		System.setProperty("mail.host", mailhost);		
		URL url = new URL("mailto:" + mailTo);
		URLConnection urlConn = url.openConnection();
		PrintWriter out = new PrintWriter(new OutputStreamWriter(urlConn.getOutputStream( )));

		out.println("from:" + mailFrom);
		out.println("to:" + mailTo);
		out.println("cc:" + cc );
		out.println("bcc:" + bcc );
		out.println("subject:"+ subject );
		out.println("");  
		out.println(text );
		out.flush();
		out.close();
	
	}

What about if I have a proxy server?

Most Socket and URLConnection implementations will allow you to pass your data through a proxy server. You need to set at least two System properties that each implementation will look for --"http.proxyHost" and "http.proxyPort" . If you have a browser that is utilizing a proxy server, you will generally find these settings under a Network Settings dialog.

Some proxy servers require you to log in. If you set "http.proxyUser" and "http.proxyPassword", the Socket or URLConnection implementations will pass these along.

Calling the Function

NetworkFunctions.setupProxySettings("myProxy.com", "8888", "boris","b3ar");

If you don't have to authenticate, call the function without the last two strings.

NetworkFunctions.setupProxySettings("myProxy.com", "8888", null,null);

Function code

public static void setupProxySettings(String proxyHost, String proxyPort, String user, String pwd){
		
if (proxyHost != null && proxyPort != null){ 
	System.setProperty("http.proxyHost", proxyHost); 
	System.setProperty("http.proxyPort", proxyPort);
	// some proxies may require http.proxyUser  and http.proxyPassword ....
	if (user != null && pwd !=null){
		System.setProperty("http.proxyUser", user); 
		System.setProperty("http.proxyPassword", pwd);
	}
}	
	
}

Copyright (c)2004 Gervase Gallant gervasegallant@yahoo.com