December 20, 2014
Hot Topics:

Serializing an Object via a Client/Server Connection

  • April 6, 2006
  • By Matt Weisfeld
  • Send Email »
  • More Articles »

Creating the ObjectStreams

After the socket connection is made, you need to create a couple of object streams, at least in this example. Again, you will keep it simple so you don't have to worry about synchronization. You create an ObjectOutputStream, called clientOutputStream. This allows the Client to write the Employee object to clientOutputStream.

Taking a look at the Sun documentation regarding the ObjectOutputStream is helpful: "an ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream. The objects can be read (reconstituted) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the stream. If the stream is a network socket stream, the objects can be reconstituted on another host or in another process".

In essence, you are stuffing the Employee object, in this case joe, into a "pipe" that is connected to a server (that you will construct next). First, you need to associate the object streams with the socketConnection object you created earlier. The code for this is as follows.

ObjectOutputStream clientOutputStream = new
   ObjectOutputStream(socketConnection.getOutputStream());
ObjectInputStream clientInputStream = new
   ObjectInputStream(socketConnection.getInputStream());

This is a good example of a Java filter. Java I/O uses filters extensively and this is one of those places. By associating the object streams with the socket you created, actual socket information is "filtered" and, in effect, hidden from you. All you have to do from now on is to read and write to and from the object streams; we don't have to worry about the socket. This keeps you focused on the layer that you interact with directly. It also allows you to change things like the URL and virtual socket without forcing you to change a lot of code.

Writing the Employee Object to the Network

Once the object streams are created, you can write the Employee object joe to the network. This is accomplished with the following line of code.

clientOutputStream.writeObject(joe);

Notice how simple this code is. All you are doing is using the writeObject() method of the OutputStream class with joe as a parameter. You don't have to worry about the socket, the URL, or anything about the network connection. The SDK API states that "the writeObject() method is responsible for writing the state of the object for its particular class so that the corresponding readObject() method can restore it".

At this point, the joe object is loaded into the "pipe" that connects the Client to the Server. If the Server connection is not present, an exception will be generated. In fact, if the Server is not running, exceptions will be generated earlier in the process; you will explore many of these exception conditions.

The joe object is now "pipe" and ready to be retrieved by the Server, which will read it, update it, and then send it back. Once the Server is done with it, the Client can take the object back off the "pipe."

Retrieving the updated Employee Object from the Network

Remember that this application was designed with simplicity in mind. Thus, once the Client sends the joe object to the Server, it simply waits for the object to come back. This is accomplished by using the following line of code.

joe= (Employee)clientInputStream.readObject();

You are using two separate object streams to do the job. The Client and the Server will share the connections (pipes). Obviously, the output stream for the client will be the input stream for the Server and visa versa. Thus, the Client will put the initial joe object on its output stream. The Server then will take that object off its input stream.

The SDK API states that "the method readObject() of the input stream is used to read an object from the stream. Java's safe casting should be used to get the desired type." In Java, strings and arrays are objects and are treated as objects during serialization. When read, they need to be cast to the expected type.

After altering the joe object, the Server puts joe in its output stream. Then, the Client retrieves joe from its input stream. This may seem confusing at first; however, once you run the code it will become clearer. You can think of it as a two-lane highway from one city to another. There is an eastbound and a westbound side—and each can only go in one direction.

Once the Client retrieves the joe object, you print out the attributes of the object so that you can verify that the Server actually did get possession of the object and altered the attributes employeeNumber and employeeName.

System.out.println("employeeNumber= " + joe .getEmployeeNumber());
System.out.println("employeeName= "   + joe .getEmployeeName());

Closing the Object Streams

Finally, you need to do some housekeeping. In this case, you will close both the input and output streams with the following lines.

clientOutputStream.close();
clientInputStream.close();

This completes the code for the Client. The only other issue that you should pay attention to is that the code in the Client is incorporated inside a try/catch block. This is required for compilation. As stated earlier, I will cover the various exceptions and how we handle them in later articles. Listing 2 contains the complete code for the Client.

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

public class Client {

   public static void main(String[] arg) {
      try {
         Employee joe = new Employee(150, "Joe");

         System.out.println("employeeNumber= "
                            + joe .getEmployeeNumber());
         System.out.println("employeeName= "
                            + joe .getEmployeeName());

         Socket socketConnection = new Socket("127.0.0.1", 11111);


         ObjectOutputStream clientOutputStream = new
            ObjectOutputStream(socketConnection.getOutputStream());
         ObjectInputStream clientInputStream = new 
            ObjectInputStream(socketConnection.getInputStream());

         clientOutputStream.writeObject(joe);

         joe= (Employee)clientInputStream.readObject();

         System.out.println("employeeNumber= "
                            + joe .getEmployeeNumber());
         System.out.println("employeeName= "
                            + joe .getEmployeeName());

         clientOutputStream.close();
         clientInputStream.close();

      } catch (Exception e) {System.out.println(e); }
   }
}

Listing 2: The Client

The Server

With the Client code complete, you now turn your attention to the Server. For obvious reasons, the Client cannot function without the Server. So, before you can demonstrate the Client code, you have to get the Server up and running. It is something like the chicken and egg dilemma—which comes first, the Client or the Server? In reality, you need both for the system to work. However, one thing is for certain; the Server must be started before you can process any Client activities. In fact, the Server can handle multiple Clients, a scenario that you will investigate later.

Here are the steps that need to be completed to properly create the Server.

  • Create a reference to the Employee object
  • Create a server socket connection
  • Create a socket to accept an object from the "pipe"
  • Create an ObjectOutputStream
  • Create an InputOutputStream
  • Read an Employee object
  • Change the Employee number
  • Change the Employee name
  • Write the revised employee object to the output stream
  • Close the object streams

Remember that in this system, the Server never actually instantiates an Employee object. It uses the one sent to it by the Client.

Create a Reference to the Employee Object

In the Server, you are going to use an Employee object sent from the Client. To do this, the Server must create a reference to an Employee object. When the object is received from the Client, the reference then "points" to that object. The following code created the reference.

Employee employee = null;

At the time this reference is defined, you set it to null.

Creating the Socket

There are actually two steps to creating the Socket connection for the Server. First, you create an instance of the class ServerSocket.

The SKD API states, "this class implements server sockets. A server socket waits for requests to come in over the network and then creates a server socket, bound to the specified port."

ServerSocket socketConnection = new ServerSocket(11111);

The difference here is that you do not have to specify a URL, only the virtual socket. In the Client example, you needed to "locate" the Server by using the URL. In the case of the Server, you will read the object directly off the virtual port. The port number must be the same for the Server and the Client.

Once the connection to the virtual port is in place, the Server will wait for an object to "show up" at the port. Before you wait, you write a message to the console indicating the Server is up and running.

System.out.println("Server Waiting");

However, it is not the connection to the virtual port that initiates the "Waiting" state. The following line of code accomplishes that task.

Socket pipe = socketConnection.accept();

According to the SDK API, "the accept() method listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made."

You create a Socket object that you call pipe. Using the accept() method, you now simply wait for something to appear at the virtual socket. That something is the object sent from the Client.

Creating the ObjectStreams

As with the Client, you create two object streams, one for the input and one for output. These are the complements of the streams created in the Client. The output stream of the Client connects to the input stream of the Server and visa versa.

ObjectInputStream serverInputStream = new
   ObjectInputStream(pipe.getInputStream());

ObjectOutputStream serverOutputStream = new
   ObjectOutputStream(pipe.getOutputStream());




Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel