Chapter 26

Network-Aware Programming


CONTENTS


Network-aware programming with Java is not very hard to understand. Only a few classes and procedures need to be followed when you're dealing with the java.net package. The tricky part is understanding exactly how communication takes place. Once you have this understanding and you know what methods and procedures to use in the java.net package, you should be able to develop network-enabled Java programs with very little trouble. This chapter gives you a deeper understanding of how communication takes place in Java and on the Internet, and what you need to know to effectively design a Java program to connect to the Internet, a server, or even another applet.

Much of the material in this chapter is based on java.net. Note that Chapter 33, "Package java.net," gives a complete overview of the java.net package in the Java class library and you should refer to it periodically throughout this chapter. You can also use it if you want more details about the classes and methods used in this chapter.

The Server Discussion

As you know, a server's job is to facilitate and house information for clients in a network. In this section, you'll learn how to create a basic server in Java.

What makes up a server? The following attributes contribute to a Java program becoming a server:

Typically, a server isn't designed to have a spiffy user interface; that's reserved for the client part of the application-the part usually seen by the application's user. Server applications are more function than form.

The first class to discuss in the java.net package is the java.net.ServerSocket class. ServerSocket is responsible for how TCP deals with retrieving a port, which is done when creating an instance of the ServerSocket class. The following shows an example using port 1234:

try {
    theServerSocket = new ServerSocket( 1055 );
} catch(IOException e) {}

Note
If the port you specified is already in use, then an IOException might be raised. If that happens, try using another port. The higher the port number you choose, the less likely it is to be in use.

Once you successfully get a port for a server, you need to have it continually listen for any activity by using the method accept() in the ServerSocket class:

try {
    Socket s = theServerSocket.accept();
} catch(IOException e) {}

This method cycles continually, listening to the designated port until a request comes through. If a request comes through and is successful, the method accept() returns a class Socket containing a connection to the client that initially requested a connection.

The returned class java.net.Socket represents an actual TCP connection. When a socket is created from the method accept(), a connection has been successfully opened between the client and the server. A Socket class can use an IP address or host name, a port, or both at the same time to establish a connection. You will see more of this class in subsequent sections about the client.

If everything goes smoothly, then you should be at the stage where you can begin receiving and sending information between the client and the server. The two methods in the Socket class responsible for that are the getInputStream() and the getOutputStream(). The getInputStream() returns an InputStream from the java.io package, and getOutputStream returns an OutputStream from the java.io package. You do your communicating between the client and the server in these returned classes. You have pretty much finished using networking tools in Java; now you need to implement streams.

The Server Workshop

Listing 26.1 is a server for the client/server example in this chapter. Go ahead and open a new file in your text editor, enter the code for Listing 26.1, and then save it as myServer.java. (The code for Listing 26.1 is available from this book's CD-ROM.)


Listing 26.1. The code for myServer.java.
 1:import java.io.*;
 2:import java.net.*;
 3:import java.awt.*;
 4:
 5:public class myServer extends Frame {
 6:
 7:        TextArea txtPane;
 8:
 9:        myServer() {
10:
11:            //Create the Interface
12:            super("The Server v 1.0");
13:            txtPane = new TextArea("Status Window:\n", 10, 30);
14:            add("Center", txtPane);
15:            pack();
16:            show();
17:
18:            ServerSocket theSocketServer = null;
19:            Socket socketReturn = null;
20:            InputStream rawDataIn = null;
21:
22:    try {
23:
24:        theSocketServer = new ServerSocket( 1055 );
25:        txtPane.appendText( "Initializing the port... \n");
26:
27:        //Listen at the port 1055
28:        txtPane.appendText( "Listening... \n");
29:        socketReturn = theSocketServer.accept();
30:
31:        //Connection has been achieved with client
32:        txtPane.appendText( "Connected to a Client \n");
33:
34:        //Get data from the Socket
35:        rawDataIn = socketReturn.getInputStream();
36:        DataInputStream DataIn = new DataInputStream(rawDataIn);
37:
38:        //Print Data our in the Statue Window
39:        String Value = DataIn.readLine();
40:        txtPane.appendText("Hello: " + Value + "!");
41:
42:        }
43:         catch( UnknownHostException e) {
44:            txtPane.appendText("Unable to find Server. Error" + e);
45:         }
46:         catch( IOException e ) {
47:            txtPane.appendText("IO Error has been raised. Error " + e);
48:        }
49:    }
50:
51:    public static void main(String argv[]) {
52:
53:            new myServer();
54:    }
55:
56:    public boolean handleEvent(Event event) {
57:
58:        if(event.id == Event.WINDOW_DESTROY) {
59:
60:            System.exit(0);
61:            return true;
62:        }
63:        return super.handleEvent(event);
64:    }
65:}

In Listing 26.1, lines 12 to 16 should be nothing new to you; they are simply the code that builds the user interface (UI) for this application. Besides a frame, the only UI component created in this code is a TextArea because it has a method called appendText() that lets you attach text to the end of text already contained in a given TextArea. In effect, you're making a large status window where you can watch the application's progress.

Following the UI, Lines 18 to 20 are responsible for initializing all the network-related variables, including the streams that will accept and retrieve the input and output from a client. Notice that for simplicity's sake this server is only initializing an InputStream (Line 20) so it can just receive information from the client. In most real-world, and more complex, situations you want to have both streams to receive and send data across the line.

Line 24 initializes the server port, and Line 29 executes the accept() method to begin listening on that port. If a request comes in on the port, then Lines 35 and 36 are invoked to retrieve the InputStream from the connection, and on Line 39, the InputStream is placed into the String variable Value. On the next line (Line 40), the information retrieved from the client is printed out in TextArea on the server.

The only other major piece of code that should be discussed are Lines 56 through 63, which shouldn't be anything new to you. These lines enable you to exit from the application without raising any exceptions.

Your next step is to compile the application; however, you shouldn't run it yet since the client hasn't been created. That will be the next step to accomplish before you can see your client/server application come to life.

The Client Discussion

The primary role of a client is to have a well-developed user interface. Usually, it is the client that users see whenever they execute your programs.

Once you have a user interface in place, your next step is to use the Socket class in the java.net package to request a connection with a port on the server. The following list describes a client's key features:

In Java, a client application uses the Socket class to connect to a particular port. The following code lines show an example of creating an instance of the Socket class on a client application; the first number is the IP address (or you can use the host name) and the port from which it should request a connection to.

try {
     Socket s = new Socket("123.123.123.123", 1234);
} catch(IOException e) {}

When a connection has been successfully established, you can use the same two methods-getOutputStream()and getInputStream()-you used in the server example. By using these streams, you can send information to the server and get information back.

In the next section, you actually write the client side of the sample application.

The Client Workshop

Open up your text editor and enter the code from Listing 26.2; when you're done, go ahead and compile it. (Note that the code for Listing 26.2 is available from this book's CD-ROM.)


Listing 26.2. The code for myClient.java.
 1:import java.awt.*;
 2:import java.net.*;
 3:import java.io.*;
 4:
 5:public class myClient extends Frame {
 6:
 7:    //Variables for UI
 8:    Button btnServer;
 9:    TextField txtInput;
10:
11:    //Initialize Output Streams
12:    OutputStream rawDataOut = null;
13:    PrintStream DataOut = null;
14:
15:    //Initialize Socket
16:    Socket theClientSocket = null;
17:
18:    myClient() {
19:
20:        //Create the Interface
21:        super("The Client");
22:        setLayout(new FlowLayout());
23:        add(new Label("Enter Your Name: "));
24:        txtInput=new TextField(25);
25:        add(txtInput);
26:        btnServer=new Button("Send to Server");
27:        add(btnServer);
28:        pack();
29:        show();
30:        super.resize(400, 100);
31:
32:        try {
33:
34:            //Instantiate a new Socket
35:            theClientSocket = new Socket("127.0.0.1", 1055);
36:
37:            rawDataOut = theClientSocket.getOutputStream();
38:            DataOut = new PrintStream(rawDataOut);
39:
40:        } catch( UnknownHostException e) {
41:            System.out.println("Unable to find the Server. Error " + e);
42:
43:        } catch ( IOException e ) {
44:            System.out.println("An IO error has been raised. Error " + e);
45:        }
46:    }
47:
48:    public boolean handleEvent(Event event) {
49:
50:    if (event.id == Event.ACTION_EVENT && event.target == btnServer) {
51:        clickedBtnServer();
52:        return true;
53:    } else if (event.id == Event.WINDOW_DESTROY) {
54:        System.exit(0);
55:        return true;
56:    }
57:    return super.handleEvent(event);
58:    }
59:
60:    public static void main(String argv[]) {
61:
62:        new myClient();
63:    }
64:
65:    public void clickedBtnServer() {
66:
67:        // Send Data to Server
68:        try {
69:            DataOut.print(txtInput.getText());
70:            //Close the Socket
71:               theClientSocket.close();
72:        } catch(Exception e) {}
73:    }
74:}

Listing 26.2 is the sample client application. Starting at the top, notice that besides initializing two UI components (Lines 8 and 9), you are just initializing the output stream (Lines 12 and 13 ) for this application. That's because this is a simple model, so the client application will just be sending information to the server. In most cases, you use both input and output streams so you can get responses from the server. Finally, the Socket is initialized on Line 16.

Lines 21 through 30 build the interface for the application. Line 35 creates an instance of the Socket class that's sent to the server requesting a connection. Notice that you're using the local IP address because both the client and the server reside on your system locally.

In Lines 37 through 38, you see the code for retrieving the output stream from the Socket connection; this task is done by using the getOutputStream() method on Line 37.

The handleEvent() method on Line 48 checks for two actions: whether the button btnServer has been clicked (Line 50) or the Event.WINDOW_DESTROY has been invoked (Line 53). If the button btnServer is clicked, then the clickedBtnServer() method (Line 51) is called. This method, located on Lines 65 through 73, basically sends out the contents of the text box txtInput to the Socket so it can go to the server on Line 69. On Line 71, it closes the connection to the Socket.

The main() method (Lines 60 to 63) merely creates an instance of the class myClient using the myClient() constructor method.

Executing the Client/Server Application

When you execute the myServer and myClient applications, order is crucial if you want the demonstration to work properly. The myServer application should be loaded first so it can start listening at port 1055, then load the client application so that when it requests a connection on that port, it will get a response.

First, run the myServer application and watch the status pane in the server application as it initializes the port and starts to listen. When the myServer application looks like the one shown in Figure 26.1, then you are ready to execute the client application.

Figure 26.1: The myServer application listening at port 1055.

Now run the myClient application while leaving the myServer application up. When you load the myClient application, it automatically requests a connection through that port to the server. Once a connection has been made, the server tells you it has connected to a client. (See Figure 26.2.)

Figure 26.2: The myClient application successfully connected to myServer.

At this point, you have successfully initialized the port and created a socket between these two applications. To test your client/server application, enter your name in the myClient text field, then click the Send to Server button. You will see the server application respond, as shown in Figure 26.3.

Figure 26.3.: The myClient application retrieving information from the server.

Technical Note
If you are using Windows 95 and an earlier version of the JDK prior to 1.0.2, you may experience problems retrieving information from the server.

Obviously, this is a very simple client/server application, but it does illustrate the material needed to develop more functional programs. You should now have a general understanding of how TCP/IP works and know how to work the methods in the java.net package to create client/server applications that can communicate with each other.

Inter-Applet Communication

Sockets aren't the only way to make your programs network aware. Another technique, known as inter-applet communication, is much easier to understand and fairly easy to do. Unlike the client/server model you used in the last section, inter-applet communication is based on a peer-to-peer networking environment in which there really is no designated server or client; each participant merely contributes resources and communicates.

When dealing with inter-applet communication, there are no complex procedures to follow. There are two key things you need to do to implement inter-applet communication:

The method getAppletContext() is a member of the java.applet.Applet class. It returns an object known as AppletContext(). This class contains information about the applet's environment. The method getAppletContext() actually provides more information than just the existence of other applets in the environment; it's used in the next section when we discuss having an applet communicate with an Internet browser.

Since getAppletContext() actually returns the object AppletContext, which contains information about the applet's environment, the actual method that does the getting is a member of the AppletContext class called getApplet(). The getApplet() method takes a String that should contain the name of the applet you want to get information about.

Note
The NAME parameter is an optional part of the APPLET tag in HTML code. NAME is used to identify a name for a particular applet. For example, even though the class of this applet is myApplet, the name that it will be referred to by other applets is theApplet:
<APPLET CODE=myApplet.class NAME=theApplet WIDTH=100 HEIGHT=100> </APPLET>
When an applet is going to be referenced by another for communication purposes, you must give that applet a name.

The following is an example of using the getAppletContext().getApplet() method for an applet named theApplet:

Applet a = getAppletContext().getApplet("theApplet");

Note
Another method you can use is getApplets(), which returns a list of all the applets it found in the environment.

Now that you have a handle on the applet you want to communicate with, you need to see how to pass events from one applet to the other. For example, Applet A wants to communicate with Applet B, and it has created an Applet object referring to Applet B. Applet A gets an event from the user (such as a button click) in the handleEvent() method, so you want to pass that event off to Applet B:

public boolean handleEvent(Event event) {
    Applet a = getAppletContext().getApplet("theApplet");
    return a.handleEvent(event);
}

In the Applet B event handler, look for an event coming from Applet A and respond accordingly.

With event handling, it's a matter of having one applet pass an event to the other applet, which is the tricky part of inter-applet communication. Once you have mastered that, the rest is easy.

The First Applet

Begin by creating the applet First. Open a clean window in your text editor and enter the code for First.java, shown in Listing 26.3. (The code for Listing 26.3 is available from this book's CD-ROM.) The First applet will be the one receiving events from the applet.


Listing 26.3. The code for First.java.
 1:import java.awt.*;
 2:
 3:public class First extends java.applet.Applet {
 4:
 5:    //Variables for UI
 6:    Label lblOutput;
 7:
 8:    public void init() {
 9:
10:        //Create the UI
11:       add(new Label("The First applet."));
12:       lblOutput = new Label("Click on a button in the Second applet.");
13:       add(lblOutput);
14:    }
15:
16:    public boolean handleEvent(Event event) {
17:
18:        if ("One".equals(event.arg)) {
19:            lblOutput.setText("You clicked: One");
20:            return true;
21:        } else if ("Two".equals(event.arg)) {
22:            lblOutput.setText("You clicked: Two");
23:            return true;
24:        } else if ("Three".equals(event.arg)) {
25:            lblOutput.setText("You clicked: Three");
26:            return true;
27:        }
28:    return super.handleEvent(event);    }
29:
30:}

Lines 11 to 13 create the UI for the applet. The only other method in this applet is the handleEvent() method (starting on Line 16) in the applet. The handleEvent() method includes three if expressions (Lines 18, 21, and 24); each one checks to see whether the event being passed to it has an argument that's the label for the command button in the applet Second (the one created in the subsequent section). In response, it will change the label lblOutput to show the user that, indeed, a particular button from applet Second was clicked (Lines 19, 22, and 25).

The Second Applet

Here is the code for the second applet (see Listing 26.4). The applet Second is responsible for doing the sending to the applet First.


Listing 26.4. The code for Second.java.
 1:import java.awt.*;
 2:import java.applet.*;
 3:public class Second extends java.applet.Applet {
 4:
 5:        //Declare the UI variables
 6:        Button btnOne;
 7:        Button btnTwo;
 8:        Button btnThree;
 9:
10:        public void init() {
11:
12:                //Build the UI
13:                btnOne = new Button("One");
14:                add(btnOne);
15:                btnTwo = new Button("Two");
16:                add(btnTwo);
17:                btnThree = new Button("Three");
18:                add(btnThree);
19:
20:        }
21:
22:public boolean handleEvent(Event event) {
23:
24:    if (event.id == Event.ACTION_EVENT && event.target == btnOne) {
25:        Applet f = getAppletContext().getApplet("theFirst");
26:        return f.handleEvent(event);
27:        } else if (event.id == Event.ACTION_EVENT && event.target == btnTwo) {
28:        Applet f = getAppletContext().getApplet("theFirst");
29:        return f.handleEvent(event);
30:       } else if (event.id == Event.ACTION_EVENT && event.target == btnThree) {
31:        Applet f = getAppletContext().getApplet("theFirst");
32:        return f.handleEvent(event);
33:    }
34:
35:    return super.handleEvent(event);}
36:}

Starting with the life cycle method init(), Lines 13 to 18 build the interface. Notice, though, that the interface consists of three buttons labeled "One" (Line 13), "Two" (Line 15), and "Three" (Line 17). These labels help the applet First distinguish what to display in the output label.

The method handleEvent() (beginning on Line 22) has three if expressions (Lines 24, 27, and 30). Each of the if expressions looks for each of the three command buttons to see whether they were clicked. If one of the buttons was clicked, then each method uses the method getAppletContext()getApplet to retrieve the applet First and instance it to variable f, using the name theFirst (Lines 25, 28, and 31). Then, on the following line (Lines 26, 29, and 31), it sends the event to the applet First so that it can handle it. At that point, applet Second has done its job by finding out which button was clicked and sending the event with the appropriate attributes to the applet First. Now it waits until one of the buttons is clicked again.

Executing the Inter-Applet Communication Example

Now that you have created both files, it's time to compile and execute each one. You can compile both of them using the javac.exe command. Since these are applets, you can't use the java.exe interpreter; however, you can use the applet viewer that comes with the JDK. To use the applet viewer, though, you need to have an HTML file referring to both of these applets. Listing 26.5 shows the code for index.html. Go ahead and create index.html in your text editor and enter the HTML code from Listing 26.5.


Listing 26.5. The code for index.html.
1:<HTML>
2:<BODY>
3:<applet code=First.class name=theFirst width=250 height=100></applet>
4:<applet code=Second.class  width=200 height=100></applet>
5:</BODY>
6:</HTML>

Now you're ready to actually run the two applets through the applet viewer. Make sure both applets (First and Second) are in the same directory as the index.html and that the file applet viewer.exe that comes with the JDK is accessible from that directory. Finally, you can invoke the applet viewer by typing the following:

appletviewer index.html

You should then see two applets pop up on your desktop. (See Figure 26.4.)

Figure 26.4: Inter-applet example with both applets initialized.

Once the applets have finished loading, you're ready to begin by clicking any of the buttons on the Second applet pane. This creates an event inside the applet, which responds by kicking another message to the First applet. Next, the First applet displays what button was clicked on the Second applet. (See Figure 26.5.)

Figure 26.5: Inter-applet example with the button Two clicked.

Applet Communication with the Browser

The getAppletContext() method can also be used to facilitate communicating to a browser from inside the applet itself. There are several ways to communicate to the browser externally (such as using HTML tags and attributes); however, applets are somewhat limited in what they can do internally. In this section, you'll learn about two methods directly related to browser communication-both deal with sending information from the applet to the host browser.

However, before you can deal with that you need to learn about another class in the java.net package called the URL class. URL stands for Uniform Resource Locator; you can use this class to house information on URLs from almost any location on the Internet. You can also use other Internet protocols besides HTTP, like FTP and gopher. Here's an example of creating a new URL for access to the Web site http://café.symantec.com:

try {
    URL myWebsite = new URL("http://café.symantec.com");
} catch(MalformedURLException e) {}

There are several other constructors for this class, including one for specifying the protocol and port for a given URL reference (see Chapter 33 for more information). Once you have a URL, you can pass it to your browser by using the showDocument() method from getAppletContext().

The other method that comes from getAppletContext() is the showStatus()method, used for displaying messages in the browser's bottom status bar. This example shows how to display the line Please wait for the applet to load... in the user's browser status bar:

getAppletContext().showDocument("Please wait for the applet to load…");

Now you'll create a real-world example that sends requests to an Internet browser (in this case Internetscape, but it should work for any Java-capable browser) to either go to the Java home page (http://www.javasoft.com) or FTP to the directory where the JDK is located on the Java site (ftp://ftp.javasoft.com/pub).

In your text editor, create a new file and enter the code in Listing 26.6; save it as BrowserLink.java.


Listing 26.6. The code for BrowserLink.java.
 1:import java.net.*;
 2:import java.awt.*;
 3:
 4:public class BrowserLink extends java.applet.Applet {
 5:
 6:        //Declare variables
 7:        URL urlJava;
 8:        URL urlJDK;
 9:        Button btnFirst;
10:        Button btnSecond;
11:
12:    public void init() {
13:
14:        //Build UI
15:        btnFirst = (new Button("Java Home Page"));
16:        add(btnFirst);
17:        btnSecond = (new Button("The JDK download Directory"));
18:        add(btnSecond);
19:    }
20:
21:    public void start() {
22:
23:        //Check to make sure the URL is accessible
24:        try {
25:            urlJava  = new URL("http://www.javasoft.com");
26:            urlJDK = new URL("ftp", "ftp.javasoft.com", "/pub");
27:        } catch (MalformedURLException e) {
28:            System.out.println("Unable to retieve URL. Error: " + e);
29:        }
30:    }
31:
32:    public boolean handleEvent(Event event) {
33:
34:    if (event.id == Event.ACTION_EVENT && event.target == btnFirst) {
35:            getAppletContext().showDocument(urlJava);
36:            return true;
37:        }else if (event.id == Event.ACTION_EVENT && event.target == btnSecond){
38:            getAppletContext().showDocument(urlJDK);
39:            return true;
40:        }
41:        return super.handleEvent(event);
42:    }
43:}

The UI is built in the init() life-cycle method in Lines 15 through 18. Inside the life cycle method start() (beginning with Line 21), the life cycle method is a try block, which is used to make sure that the two URLs, http://www.javasoft.com (Line 25) and ftp://ftp.javasoft.com (Line 26), are valid and accessible from the current environment (Lines 24 through 29).

The handleEvent() method (starting on Line 32) contains two if expressions: one to determine whether btnFirst is clicked (Line 34) and the other to determine whether btnSecond is clicked (Line 37).

If the first if expression (Line 34) returns true, meaning that btnFirst was indeed pressed, then the showDocument() method (Line 35) is invoked, going to the URL address http://www.javasoft.com. However, if the second if expression returns true, meaning that the button btnSecond is clicked, then on Line 38 the method showDocument() is used to take the user to the directory where the JDK is available for downloading on the JavaSoft site ftp://ftp.javasoft.com/pub.

Go ahead and compile Listing 26.7 in a file called BrowserLink.java. Your next step is to create an HTML file to run it out of, which is shown in Listing 26.7. In another clean text editor, create the file BrowserLink.html and enter the code in Listing 26.7.


Listing 26.7. The code for BrowserLink.html.
1:<HTML>
2:<HEAD>
3:</HEAD>
4:<BODY>
5:<APPLET CODE=BrowserLink.class WIDTH=200 HEIGHT=100> </APPLET>
6:</BODY>
7:</HTML>

Now you're ready to execute and run the program. With both files (BrowserLink.java and BrowserLink.html) in the same directory, load the HTML page BrowserLink.html in your Internet browser. This example uses Netscape Navigator, but any Internet browser will do.

You can see in Figure 26.6 that there are two command buttons available. The first one, "Java Home Page," is btnFirst, and the second, "The JDK Download Directory," is btnSecond. Click the Java Home Page button and watch as your browser automatically loads the URL http://www.javasoft.com. (See Figure 26.7.)

Figure 26.6: The BrowserLink applet loaded.

Figure 26.7: The JavaSoft home page.

As you can see, the applet was replaced with the JavaSoft home page. Now, go back to the applet BrowserLink and click the JDK Download Directory button; this time, the applet will be replaced by the directory (including Sun's disclaimer) where you can download the JDK. (See Figure 26.8.)

Figure 26.8: The JavaSoft FTP archive in the /pub directory.

There are many ways for an applet to interact with the browser. However, always remember the trite security model for Java applets.

Java Communication with the Internet Using URLConnection

The final topic discussed in this chapter expands on the information in the previous section. Instead of retrieving information through the browser, you could retrieve information directly from the Internet to your applet. One way to do that is by using the class URLConnection, which represents a connection to a specified URL on the Internet. URLConnection is the class used to retrieve information from a URL passed to it. This is an example of how it's used:

try {
    URL myURL = "http://café.symantec.com";
    URLConnection myConnection = URLConnection.openConnection(myURL);
} catch(MalformedException e) {}

Once you have a valid connection, use getInputStream() and filter it through the DataInputStream, where you can successfully retrieve information directly to the applet.

Another method you can use is the openStream() method directly from the java.net.URL class.

The following example in Listing 26.8 is a Java application. When you click the command button, it will access the JavaSoft home page (http://www.javasoft.com) and retrieve the information, as a browser would.


Listing 26.8. The code for Retrieve.java.
 1:import java.net.*;
 2:import java.awt.*;
 3:import java.io.*;
 4:
 5:public class Retrieve extends Frame {
 6:
 7:    //Declare variables
 8:    Button btnRetrieve;
 9:    TextArea txtPane;
10:    static URL urlJava;
11:    static URLConnection conJava;
12:    InputStream rawInput;
13:
14:    Retrieve() {
15:
16:        //Build the UI
17:        super("The Retrieve Application");
18:        setLayout(new FlowLayout());
19:        btnRetrieve = new Button("Retrieve the JavaSoft home page.");
20:        add(btnRetrieve);
21:        txtPane = new TextArea(30,70);
22:        add(txtPane);
23:        pack();
24:        show();
25:
26:    }
27:
28:    public static void main(String argv[]) {
29:
30:        new Retrieve();
31:    }
32:
33:    public boolean handleEvent(Event event) {
34:
35:        String Value;
36:
37:        if (event.id == Event.ACTION_EVENT && event.target == btnRerçâeve) {
38:            clickedbtnRetrieve();
39:            return true;
40:        } else if (event.id == Event.WINDOW_DESTROY) {
41:            System.exit(0);
42:            return true;
43:        }
44:        return super.handleEvent(event);
45:    }
46:
47:    public void clickedbtnRetrieve() {
48:
49:        //Check to make sure the URL is accessible
50:        try {
51:            urlJava  = new URL("http://www.javasoft.com");
52:        } catch(MalformedURLException e) {
53:            System.out.println("Unable to retieve URL. Error: " + e);
54:        }
54:
55:
56:        //Retrieve the information
57:        try {
58:            conJava = urlJava.openConnection();
59:            rawInput = conJava.getInputStream();
60:            DataInputStream DataIn = new DataInputStream(rawInput);
61:
62:            //Read and display data.
63:            for (int i = 1; i < 30; i++) {
64:
65:            String Value = DataIn.readLine();
66:            txtPane.appendText(Value + "\n");
67:            }
68:        } catch(IOException e) {
69:            System.out.println("an IO error has been raised. Error: " + e);
70:        }
71:       }
72:}

Starting on Lines 8 to 12, you declare variables for the UI, and Lines 17 to 24 build the UI. The main() method on Line 28 creates an instance of the class Retrieve when the application is executed.

The interesting part of this application is the handleEvent() method starting on Line 35. There are two if statements (Lines 37 and 40). The first if statement checks to see whether the button btnRetrieve is clicked. If this is true, then it will invoke the following:

Compile and run the application Retrieve, and you should see something similar to Figure 26.9.

Figure 26.9: The Retrieve application.

Warning
Be sure you're connected to the Internet before running the Retrieve application in Listing 26.8.

Next, click the button "Retrieve the JavaSoft home page," and you'll see the first 30 lines of HTML code from the site http://www.javasoft.com. (See Figure 26.10.)

Figure 26.10: The Retrieve application with the http://www.javasoft.com site downloaded.

Summary

This chapter covered how the Internet communicates and included a high-level introduction to TCP/IP and client/server architecture. You also learned about inter-applet communication and how to bounce events off one applet to another on a single home page. Finally, you saw how to let Java applets and applications communicate with the Internet. This chapter concluded with a Java example you can actually run.

Network programming gives you several ways to do the same things. Although this chapter tried to show several of the most common techniques, for each potential solution in Java, there may be alternative methods. If you're interested in learning more, a good place to start is to become familiar with all the available classes in the java.net package, described in Chapter 33. No matter what people say (myself included), network programming can be a somewhat complex topic-but in the real world, it's a necessity that your Java programs have the capability to communicate with each other and the environment around them.