Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

Network Programming - Sockets

Java Programming, Lesson # 560, Revised 02/20/98.

Preface

Students in Prof. Baldwin's Advanced Java Programming classes at ACC are responsible for knowing and understanding all of the material in this lesson.

Introduction

Sockets come in three varieties which are implemented by the Java classes named Socket, DatagramSocket, and ServerSocket. The first two socket classes represent TCP and UDP communications respectively.

Generally, the two socket classes are used to implement both clients and servers , while the ServerSocket class is only used to implement servers. We will see numerous examples of socket programming in this and subsequent lessons.

This lesson will concentrate on the use of the Socket class. The other two classes will be covered in subsequent lessons.

Socket programming provides a low-level mechanism by which you can connect two computers for the exchange of data. One of those is generally considered to be the client while the other is considered to be the server.

The client initiates a connection with a server. Servers wait for a clients to initiate connections.

The governing protocol will determine what happens after the connection is made. In order for two computers to communicate effectively, they must each implement some mutually acceptable application protocol

Socket programming makes it possible for you to cause data to flow in a full-duplex mode between a client and a server. This data flow can be viewed in almost exactly the same way that we view data flow to and from a disk: as a stream of bytes.

As with most stream data processing, the system is responsible for moving the bytes from the source to the destination. It is the responsibility of the programmer to assign meaning to those bytes.

Assigning meaning takes on a special significance for socket programming. In particular, as mentioned above, it is the responsibility of the programmer to implement a mutually acceptable communication protocol, at the application level, to cause the data to flow in an orderly manner. Some of the bytes are used to implement the protocol, and some of the bytes are used to transfer data.

An application protocol is a set of rules by which the programs in the two computers can carry on a conversation and transfer data in the process.

For example, we will write a program using the SMTP mail protocol to send an email message to someone. We will also write a program that implements a very abbreviated form of the HTTP protocol to download web pages from a server and to display them.

Each of these programs will involve adherence to a fairly simple protocol (at least the part that we implement will be simple).

We will also write a program that obtains the date and time from another computer. In this case, the protocol is about as simple as it can possibly be. In this case, the client will simply make the connection and listen for a string containing the date and time. In this case, the client isn't even required to make a request.

It is easy to use sockets to write code that will cause a stream of bytes to flow in both directions between a client and a server. This is no more difficult than causing a stream of bytes to flow in both directions between memory and a file on a disk.

Getting the bytes to flow is the easy part. Beyond that, you must do all of the programming to implement an application protocol that is understood by both the client and the server. Often that is the more difficult part.

Echo Program

This program implements a client that performs a simple echo test with a server by sending a line of text to the echo port which is port 7 on the server.

You must be logged onto an appropriate network for this program to run properly. However, it is possible that the network can exist completely within a single computer under some operating systems. (We will learn to cause a single computer to simulate a network under Win95 later.) Otherwise, the program will throw an exception of type UnknownHostException.

The program begins by instantiating a String object containing the name of an echo server that is being used to test the program.

This is followed by the declaration and initialization of an int variable containing the standard echo port number. The standard echo port is port 7.

Than the program gets a socket connection to port 7 on the server.

Following this, the program gets input and output streams from the socket and wraps them in the new Reader and Writer classes. You may want to pay particular attention to this, because as of this writing in January of 1998, it is difficult to find written material that explains how to use the Reader and Writer classes in conjunction with socket programming.

Once the connection is made and the input and output streams are ready to use, the program sends a line of text to the echo port on the specified server.

This causes the server to send the same line of text back to the client.

The program reads the line of text that is received and displays it.

Finally, the program closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

Assuming that you select a server that supports echo processing on port 7, the output from this program should be:

This is an echo test

If you select a server that does not support echo processing on port 7, your output will be different. For example, I tried to run this program on the server identified as "www.whitehouse.net" and the response was something like "connection refused."

This is an interesting result because, as we will see later, that URL does support the daytime port on port 13 that delivers the date and time.

Code Fragments from the Echo Program

This program is used to create a client that communicates with a server for purposes of performing an echo test.

We will begin with the first few lines in the main() method of the controlling class where we declare two local variables that you will need to recognize later.

These variables are used later to specify the server and the port on the server that we are connecting to.
 
    String server = "www2.austin.cc.tx.us";
    int port = 7; //echo port
Much of this program is wrapped in a try/catch block that I am going to ignore as I highlight these code fragments. You can see the try/catch activity in context in the complete listing of the program that appears later in the lesson.

The next code fragment is the the key statement in this program insofar as learning new material is concerned.

This statement establishes a connection with the specified port on the specified server by instantiating a new object of type Socket.

Once this object exists, it is possible to use it to communicate with the server on the specified port using the protocol prescribed for the service being delivered on that port.

The constructor for this class throws two different types of exceptions so you will need to wrap this statement in a try/catch block. The two types of exceptions are: UnknownHostException and IOException.
 
      Socket socket = new Socket(server,port);
Once you have a Socket object, you can use that object to open input and output streams that allow you to transfer data between the client and the server.

The only thing remarkable about this code is the fact that it uses the Reader and Writer capabilities of JDK 1.1. Most of the books that I have read are still using deprecated methods from JDK 1.0 in their sample programs for socket programming.

Of the many books that I reviewed on this topic, the only one that I found that had upgraded to the Reader and Writer classes was Java, How to Program, Second Edition, by Deitel and Deitel.

I find the proper use of the I/O stream library to be one of the most difficult, confusing, and tedious aspect of Java programming, and it became even more difficult with the advent of the new classes in JDK 1.1. I was thankful to find information in the Deitel book about how to use these new classes to properly construct the streams needed for socket programming.

Note that the true parameter in the last line will cause the output stream to flush automatically. Proper flushing is an important aspect of socket programming.
 
//Get an input stream from the socket
BufferedReader inputStream = 
     new BufferedReader(new InputStreamReader(
                     socket.getInputStream()));

//Get  an output stream to the socket.  Note
// that this stream will autoflush.
PrintWriter outputStream = 
     new PrintWriter(new OutputStreamWriter(
               socket.getOutputStream()),true);
The next code fragment uses the outputStream created above to send a line of text to the server, and then uses the inputStream created above to capture and display the echo that is returned from the server.

After we we display the echo, we close the socket.
 
      outputStream.println("This is an echo test");
      System.out.println(inputStream.readLine());
      socket.close();
Finally, we implement some catch blocks to deal with the different types of exceptions that can be thrown in the previous code. You can see the catch blocks in the complete program listing in the next section.

That's really about all there is to socket programming from the client viewpoint.

Beyond this, the programming complexity associated with socket programming is the result of the requirement to implement an application protocol that will successfully communicate with the server.

Program Listing for the Echo Program

You may find it helpful to take a look at the following listing of the program to see the above code fragments in context.
 
/*File Sockets03.java Copyright 1998, R.G.Baldwin
Revised 01/20/98

This program performs a simple echo test with a server
by sending a line of text to the echo port, port 7.

You must be logged onto an appropriate network for this
program to run properly.  Otherwise, it will throw
an exception of type UnknownHostException.

Most of the program is enclosed in a try/catch block to
deal with possible exceptions.

The program begins by instantiating a String object
containing the name of an echo server that you are
using to test the program.

This is followed by declaration and initialization of
an int variable containing the standard echo port number.
The standard echo port is number 7.

Than the program gets a socket connection to port 7
on the echo server.

Then the program gets input and output streams from the
socket and wraps them in the new reader classes.

Once the input and output streams are ready to use, the
sends a line of text to the echo port on the server.

The echo server sends the same line of text back to
the client.

Then the program reads the line of text that is 
received and displays it.

Then the program closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

The output from this program is:
  
This is an echo test
**********************************************************/

import java.net.*;
import java.io.*;
import java.util.*;

class Sockets03{
  public static void main(String[] args){
    String server = "www2.austin.cc.tx.us";
    int port = 7; //echo port
    
    try{
      //Get a socket, connected to the specified server
      // on the specified port.
      Socket socket = new Socket(server,port);
      
      //Get an input stream from the socket
      BufferedReader inputStream = 
                 new BufferedReader(new InputStreamReader(
                                 socket.getInputStream()));

      //Get  an output stream to the socket.  Note
      // that this stream will autoflush.
      PrintWriter outputStream = 
                   new PrintWriter(new OutputStreamWriter(
                           socket.getOutputStream()),true);

      //Send line of text to the server
      outputStream.println("This is an echo test");
      //Get echoed line back from server and display it
      System.out.println(inputStream.readLine());
        
      //Close the socket
      socket.close();
    }//end try
    catch(UnknownHostException e){
      System.out.println(e);
      System.out.println(
                       "Must be online to run properly.");
    }//end catch UnknownHostException
    catch(IOException e){System.out.println(e);}
  }//end main
}//end class Sockets03
//=======================================================//

Date/Time Program

This program implements a client that gets the date and time from the daytime port on a server that supports that port.

This program is even simpler than the previous one, because it isn't necessary to send anything to the server to get the desired result. All that is necessary to cause the server to send the desired information is to make the connection.

This program gets and displays the date and time on the server at "www.whitehouse.net".

It also displays the current date and time in Austin, TX (or wherever the program happens to be run) for comparison.

You must be logged onto an appropriate network for this program to run properly. Otherwise, it will throw an exception of type UnknownHostException.

The program begins by instantiating a String object containing the name of the server being used to test the program.

This is followed by the declaration and initialization of an int variable identifying the standard daytime port. The standard daytime port is port 13.

Than the program gets a socket connection to port 13 on the specified server.

Following this, the program gets an input stream from the socket and wraps it in the new reader classes.

This program doesn't't need an output stream because the client doesn't send anything to the server. Simply connecting is sufficient to trigger the server to send the date and time.

After the connection is made via the socket and the input stream is ready to use, the client reads a line of incoming text. This line of text contains the date and time sent by the server.

The program displays this line of text, and also gets and displays the date and time on the local system using the Date class for comparison.

Then the program closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

The output from this program for one particular run was:
 
Got socket 
Current time at www.whitehouse.net: Wed Jan 21 00:31:13 1998 
Current time in Austin, TX: Tue Jan 20 23:31:18 CST 1998 
This is an interesting output because it was run near midnight and the difference in time zones caused the date to be different in Austin, TX and in the Eastern Time Zone.

Note also that there was a five-second difference in the two clocks with the server clock appearing to be slow relative to the client clock.

Prior to running this test, I synchronized the clock in my computer with a Naval Observatory time standard in Washington, D.C. I don't know how much of the five second difference was attributable to transmission time of the data from the server to the client, and how much was due to the fact that one or the other of the clocks wasn't exactly correct.

Code Fragments from Date/Time Program

There isn't any code in this program that differs in any significant way from the previous program, other than the System.out.println() statements that display the date and time. You have seen hundreds of statement like those statements.

Therefore, I won't bore you with highlighted code fragments from this program.

Program Listing for Date/Time Program

A complete listing of this program follows.
 
/*File Sockets04.java Copyright 1998, R.G.Baldwin
Revised 01/20/98

This program gets and displays the date and time on the
server at "www.whitehouse.net".

It also displays the current date and time in Austin,
TX, or wherever the program happens to be run.

You must be logged onto an appropriate network for this
program to run properly.  Otherwise, it will throw
an exception of type UnknownHostException.

Most of the program is enclosed in a try/catch block to
deal with possible exceptions.

The program begins by instantiating a String object
containing the name of the server being used to
test the program.

This is followed by declaration and initialization of
an int variable containing the standard daytime port.
The standard daytime port is number 13.

Than the program gets a socket connection to port 13
on the daytime server.

Then the program gets an input stream from the socket
and wraps it in the new reader classes.

Once the input stream is ready to use, the client
reads a line of incoming text.  This is the
date and time sent by the server.

Then the program displays this line of text, and also
gets and displays the date and time on the local system
using the Date class.

Then the program closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

The output from this program was:

Got socket
Current time at www.whitehouse.net:
Wed Jan 21 00:31:13 1998
Current time in Austin, TX:
Tue Jan 20 23:31:18 CST 1998  
**********************************************************/

import java.net.*;
import java.io.*;
import java.util.*;

class Sockets04{
  public static void main(String[] args){
    String server = "www.whitehouse.net";
    int port = 13; //daytime port
    
    try{
      //Get a socket, connected to the specified server
      // on the specified port.
      Socket socket = new Socket(server,port);
      System.out.println("Got socket");
      
      //Get an input stream from the socket
      BufferedReader inputStream = 
                 new BufferedReader(new InputStreamReader(
                                 socket.getInputStream()));
      
      System.out.println(
                    "Current time at www.whitehouse.net:");
      System.out.println(inputStream.readLine());
      System.out.println("Current time in Austin, TX:");
      System.out.println(new Date());
        
      //Close the socket
      socket.close();
    }//end try
    catch(UnknownHostException e){
      System.out.println(e);
      System.out.println(
                       "Must be online to run properly.");
    }//end catch UnknownHostException
    catch(IOException e){System.out.println(e);}
  }//end main
}//end class Sockets04
//=======================================================//

Simple Browser Program

The next program is an extremely simple web browser program. More correctly, the next program is a simple HTTP client (web browser) implemented using sockets.

The program implements just enough of the HTTP protocol to make it capable of getting an HTML page (or any other type of file for that matter) from an HTTP server. Considerably more programming effort would be required to turn it into a useful browser, but such programming should be within the reach of the persons enrolled in Prof. Baldwin's Advanced Java Programming course at ACC

You must be logged onto an appropriate network for this program to run properly. Otherwise, it will throw an exception of type UnknownHostException.

The program begins by defining the name of a server and the number of the HTTP port on that server. The standard port number for HTTP servers is port 80.

Then the program opens a socket to the specified server on the specified port.

As in the previous programs, this program creates input and output stream objects for transferring data between the client and the server.

As mentioned earlier, the output stream will autoflush, which is critical. If the output stream isn't flushed, the server will not respond properly (presumably it may not receive all of the data until the stream is flushed).

Then the program, acting as an HTTP client, sends a GET command to the server specifying a particular path and file name. The GET command is part of the HTTP application protocol.

This causes the server to attempt to fetch the specified file and send it to the client. If the server is being properly supported on the specific port, it will send something, although that something could be an error message.

The program reads lines of text from the input stream and displays them on the standard output device. Note that even though this may be HTML data, it is displayed as ordinary text. Therefore, if it is HTML, you will see it in raw form including all of the HTML tags.

When there are no more lines to be read, a null is received. This causes the client to exit the input loop and to close the socket.

This program was tested using JDK 1.1.3 under Win95.

As of 01/20/98, the output from this program was as follows. This is a text representation of an HTML file named Test01.html. Note that the contents of this test file on the server may change over time, so you may not see exactly the same result if you compile and run this program.
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>Note that some lines of text were deleted
in the interest of brevity.

<P>This test file is used to test certain 
network programming applications.</P>

</BODY>
</HTML>

Code Fragments from the Browser Program

This program begins much like the two previous programs by getting a socket connection on port 80 of the specified server.

Following this, it instantiates stream objects for input and output using the new Reader and Writer classes. I won't highlight that code here, because it is essentially the same as what you saw in the first program in this lesson.

The HTTP protocol provides several different commands or requests that the client can send to the server. This program implements only the GET command. This is a request by the client to find and download a specified file.

The statement used by the client to request the file named Test01.html from the server is shown below.

Note that the request includes not only the file name, but also the path to that file relative to the directory that the HTTP server software considers to be the pseudo-root. This is probably not the actual root directory on the server computer, but rather is a logical root.

The server software is willing to access and deliver files from directories relative to this pseudo-root.

Note that the request is actually made by printing a line of text on the stream that is connected to the server.
 
      outputStream.println("GET /baldwin/Test01.html");
At this point, if the GET message is properly sent, it is probably safe to assume that some text will be sent back by the server, although it may consist of an error message.

The next fragment reads that text from the input stream, displays it on the standard output device, and closes the socket when there is no more data to be extracted from the input stream.
 
      String line = null;

      while((line = inputStream.readLine()) != null) 
        System.out.println(line);
        
      socket.close();
This is followed by the usual exception handling code.

An interesting exercise for the student would be to improve this program to give it additional browser characteristics.

For example, you could review the specifications for HTML and write a display method that would display the data in the style normally associated with HTML pages.

You could wrap the entire program in a Graphical User Interface with a TextArea for display and a TextField for specifying the URL.

You could review the HTTP specifications and implement additional client requests for the HTTP protocol.

Or, you could start with this program and write a "web crawler" program that would begin at some specified URL, downloading files and following links until you either terminate the program after reaching some depth level on links, or fill up your disk with downloaded files.

A safer program for starters would be a web crawler that follows links but doesn't actually save the files that it downloads. It would download each file, parse it to extract the links, and then discard everything but the links.

Program Listing for the Browser Program

A complete program listing of this program follows.
 
/*File Sockets01.java Copyright 1998, R.G.Baldwin
Revised 01/20/98

This program is a simple http client (web browser)
implemented using sockets.

The program implements just enough of the http protocol
to make it capable of getting an html page from an
http server.

You must be logged onto an appropriate network for this
program to run properly.  Otherwise, it will throw
an exception of type UnknownHostException.

Most of the program is enclosed in a try/catch block to
deal with possible exceptions.

The program begins by defining the name of a server and
the number of the http port on that server.  The standard
port number for http servers is 80.

Then the program opens a socket to the specified server
on the specified port.

Then it uses the new BufferedReader class along with the
new InputStreamReader class to open an input stream from
the socket.  These classes are wrapped around an input
stream provided by the Socket class.

Then it uses the new PrintWriter class along with the
new OutputStreamWriter class to open an output stream to
the socket.  These classes are also wrapped around an 
output stream provided by the Socket class.

The output stream will autoflush, which is critical.  If
the output stream isn't flushed, the server will not
respond (presumably it doesn't receive all of the 
output data until the stream is flushed).

Then the program, acting as an http client, sends a GET
command to the server specifying a particular path and 
file name.

This causes the server to attempt to fetch the specified 
file and send it to the client.

Then the program reads lines from the input stream and 
displays them on the standard output device.

When there are no more lines to be read, a null is 
received.  This causes the client to exit the input
loop and to close the socket.

This program was tested using JDK 1.1.3 under Win95.

As of 01/20/98, the output from this program was as 
follows.  This is a text representation of an html file
named Test01.html. Note that the contents of this test 
file on the server may change over time, so you may not
see exactly the same result when you compile and run
this program.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
   <TITLE></TITLE>
   <META NAME="Author" CONTENT="">
   <META NAME="GENERATOR" CONTENT=
"Mozilla/3.01Gold (Win95; I) [Netscape]">
</HEAD>
<BODY>

<P><B><I>Richard G Baldwin (512) 223-4758, 
<A HREF="mailto:baldwin@austin.cc.tx.us">
baldwin@austin.cc.tx.us</A>,
<A HREF="http://www2.austin.cc.tx.us/baldwin/">
http://www2.austin.cc.tx.us/baldwin/</A></I></B></P>

<H3 ALIGN=CENTER>
<A HREF="http://www2.austin.cc.tx.us/baldwin/">
Test File</A></H3>

<P>This test file is used to test certain 
network programming applications.</P>

</BODY>
</HTML>
**********************************************************/

import java.net.*;
import java.io.*;

class Sockets01{
  public static void main(String[] args){
    String server = "www2.austin.cc.tx.us";//server name
    int port = 80; //http port
    try{
      //Get a socket, connected to the specified server
      // on the specified port.
      Socket socket = new Socket(server,port);
      
      //Get an input stream from the socket
      BufferedReader inputStream = 
                 new BufferedReader(new InputStreamReader(
                                 socket.getInputStream()));

      //Get  an output stream to the socket.  Note
      // that this stream will autoflush.
      PrintWriter outputStream = 
                   new PrintWriter(new OutputStreamWriter(
                           socket.getOutputStream()),true);
      
      //Send a GET command to the server
      outputStream.println("GET /baldwin/Test01.html");

      //Declare a String to read lines into.
      String line = null;
      
      //Loop reading and displaying lines until null 
      // is received.
      while((line = inputStream.readLine()) != null) 
        System.out.println(line);
        
      //Close the socket
      socket.close();
    }//end try
    catch(UnknownHostException e){
      System.out.println(e);
      System.out.println(
                       "Must be online to run properly.");
    }//end catch UnknownHostException
    catch(IOException e){System.out.println(e);}
  }//end main
}//end class Sockets01
//=======================================================//

E-Mail Program

As of January 1998, the SMTP protocol for sending email messages can be found at http://www.gssnet.com/rfc/rfc821a.htm

This sample program is a simple SMTP client implemented using sockets.

The program implements enough of the SMTP protocol to make it capable of sending an email message to someone if you know their email name and the identity of their SMTP server.

You must be logged onto an appropriate network for this program to run properly. Otherwise, it will throw an exception of type UnknownHostException.

The program begins by instantiating a String object containing the name of an SMTP server. Although I tested this program using my SMTP server, I removed the name of my server from the program to avoid getting lots of test messages from other people who might be testing this program. It should be easy enough for you to obtain the identify of your own SMTP server and to test the program by sending messages to yourself.

You should cause the String object mentioned above to contain the name of your email server or the email server that you are using to test the program.

Instantiation of the String containing the name of the SMTP server is followed by declaration and initialization of an int variable identifying the port number for the standard SMTP mail service. The standard SMTP port is port 25.

The program gets a socket connection to port 25 on the SMTP server.

Then the program gets input and output streams from the socket as in the previous programs.

Once the connection is made and the input and output streams are ready to use, the program begins the conversation with the email server by implementing an abbreviated version of the SMTP protocol.

The SMTP protocol consists of transmitting a series of simple lines of text to the server and listening for lines of text being returned. In this program, the text that is received by the client is displayed on the standard output device, and is shown below.

After the test message has been sent, the program closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

As of 01/20/98, the output from this program (with line breaks manually inserted) was as follows.
 
220 monk.austin.cc.tx.us ESMTP 
  Sendmail 8.8.5/8.6.9 ready at 
  Tue, 20 Jan 1998 22:16:37 -0600
250 baldwin... Sender ok
250 baldwin... Recipient ok
354 Enter mail, end with "." on a line by itself

Code Fragments from E-Mail Program

The program begins by establishing the name of the SMTP server and the standard port on which that is service is normally supported. As indicated above, you should insert the name of your server in place of the highlighted string below.
 
    String server = "put your email server name here";
    int port = 25; //mail port
After this, we get a socket, get an input stream, and get an output stream just like in the previous programs. I will skip over that code in this section because you have seen it before.

The purpose of this program is to send an email message to someone, so at this point, we begin the conversation with the mail server by sending a line of text in the following format. This line of text identifies the sender of the message. Then we read and display a line.
 
      //Begin the conversation with the email server.      
      outputStream.println(
                    "mail from: put your email name here");

      System.out.println(inputStream.readLine());
Next we send a line of text to the server identifying the recipient of the message. Again, we read and display a line of text sent by the server.
 
      
      outputStream.println(
                 "rcpt to: " + "put your email name here");

      System.out.println(inputStream.readLine());
All of this is assuming that everything works as expected.

If we were really serious about writing a program that could handle this protocol, we would need to examine the text coming from the server to confirm that everything is working as expected, and take corrective action if it isn't. This would require considerably more study of the protocol specification than I have done at this point in time.

Next, we send the string "data", and as usual, we read and display a line of text from the server.
 
      outputStream.println("data");
      System.out.println(inputStream.readLine());
Following this, we construct and send the actual message followed by a period on a line by itself. Then we read and display a line of text, and close the socket.
 
      String timeStamp = (new Date()).toString();
      outputStream.println("Test message " + timeStamp);
      outputStream.println(".");
      System.out.println(inputStream.readLine());

      socket.close();
After closing the socket, we deal with the normal collection of exception handlers.

As indicated above, using this protocol would have involved considerably more code if we had been careful to adhere to the specification exactly, and had examined each of the messages received from the server to confirm that everything was going OK.

Program Listing for E-Mail Program

A complete listing of the program follows.
 
/*File Sockets02.java Copyright 1998, R.G.Baldwin
Revised 01/20/98

This program is a simple SMTP (email) client implemented
using sockets.

The program implements enough of the SMTP protocol
to make it capable of sending an email message to
someone at an SMTP server.

You must be logged onto an appropriate network for this
program to run properly.  Otherwise, it will throw
an exception of type UnknownHostException.

Most of the program is enclosed in a try/catch block to
deal with possible exceptions.

The program begins by instantiating a String object
containing the name of an email server.  Although I
tested this program using my server, I removed the
name of my server to avoid getting hundreds of test
messages from people around the world testing this 
program.

You should cause the String object to contain the name
of your email server or the email server that you are
using to test the program.

This is followed by declaration and initialization of
an int variable containing the port number for the 
standard SMTP mail service.  The standard SMTP port
is number 25.

Than the program gets a socket connection to port 25
on the email server.

Then the program gets input and output streams from the
socket and wraps them in the new reader classes.

Once the input and output streams are ready to use, the
program begins the conversation with the email server
following the SMTP protocol.

This consists of transmitting a series of simple lines
of text to the server and listening for lines of text
being returned.  The text that is received by the client
is displayed on the standard output device, and is 
shown below.

After the test message has been sent, the program
closes the socket and terminates.

This program was tested using JDK 1.1.3 under Win95.

As of 01/20/98, the output from this program (with line
breaks manually inserted) was as follows.  

220 monk.austin.cc.tx.us ESMTP 
  Sendmail 8.8.5/8.6.9 ready at 
  Tue, 20 Jan 1998 22:16:37 -0600
250 baldwin... Sender ok
250 baldwin... Recipient ok
354 Enter mail, end with "." on a line by itself
**********************************************************/

import java.net.*;
import java.io.*;
import java.util.*;

class Sockets02{
  public static void main(String[] args){
    String server = "put your email server name here";

    int port = 25; //mail port
    try{
      //Get a socket, connected to the specified server
      // on the specified port.
      Socket socket = new Socket(server,port);
      
      //Get an input stream from the socket
      BufferedReader inputStream = 
                 new BufferedReader(new InputStreamReader(
                                 socket.getInputStream()));

      //Get  an output stream to the socket.  Note
      // that this stream will autoflush.
      PrintWriter outputStream = 
                   new PrintWriter(new OutputStreamWriter(
                           socket.getOutputStream()),true);

      //Begin the conversation with the email server.      
      outputStream.println(
                    "mail from: put your email name here");

      System.out.println(inputStream.readLine());
      
      outputStream.println(
                 "rcpt to: " + "put your email name here");

      System.out.println(inputStream.readLine());

      outputStream.println("data");
      System.out.println(inputStream.readLine());

      String timeStamp = (new Date()).toString();
      outputStream.println("Test message " + timeStamp);
      outputStream.println(".");
      System.out.println(inputStream.readLine());

      //Close the socket
      socket.close();
    }//end try
    catch(UnknownHostException e){
      System.out.println(e);
      System.out.println(
                       "Must be online to run properly.");
    }//end catch UnknownHostException
    catch(IOException e){System.out.println(e);}
  }//end main
}//end class Sockets02
//=======================================================//

Summary

Once you learn how to instantiate Socket objects and how to deal with the input and output streams, writing client software using sockets in Java is easy.

The real complexity, to the extent that there may complexity, is wrapped up in understanding and implementing the various protocols required by the servers for the different services that are offered.

-end-