views:

60

answers:

2

I have a fairly complex project that boils down to a simple Client / Server communicating through object streams.

Everything works flawlessly for two consecutive connections (I connect once, work, disconnect, then connect again, work, and disconnect). The client connects, does its business, and then closes. The server successfully closes both the object output stream and the socket, with no IO errors.

When I try to connect a third time, the connection appears to go through (the ServerSocket.accept() method goes through and an ObjectOutputStream is successfully created). No data is passed, however. The inputStream.readUnshared() method simply blocks.

I have taken the following memory precautions:

  1. When it comes time to close the sockets, all running threads are stopped, and all objects are nulled out.
  2. After every writeUnshared() method call, the ObjectOutputBuffer is flushed and reset.

Has anyone encountered a similar problem, or does anyone have any suggestions? I'm afraid my project is rather large, and so copying code is problematic.

The project boils down to this:

SERVER MAIN

ServerSocket serverSocket = new ServerSocket(port);

while (true) {
    new WorkThread(serverSocket.accept()).start();
}

WORK THREAD (SERVER)

public void run() {
    ObjectInputBuffer inputBuffer = new ObjectInputBuffer(new BufferedInputStream(socket.getInputStream()));

    while (running) {
         try {
              Object myObject = inputBuffer.readUnshared();

              // do work is not specified in this sample
              doWork(myObject);
         } catch (IOException e) {   
              running = false;
         }
    }

    try {
         inputBuffer.close();
         socket.close(); 
    } catch (Exception e) {
         System.out.println("Could not close.");
    }
}

CLIENT

public Client() {
    Object myObject;
    Socket mySocket = new Socket(address, port);

    try {
         ObjectOutputBuffer output = new ObjectOutputBuffer(new BufferedOutputStream(mySocket.getOutputStream()));

         output.reset();
         output.flush();
    } catch (Exception e) {
         System.out.println("Could not get an input.");
         mySocket.close();
         return;
    }

    // get object data is not specified in this sample. it simply returns a serializable object
    myObject = getObjectData();

    while (myObject != null) {
         try {
              output.writeUnshared(myObject);
              output.reset();
              output.flush();
         } catch (Exception e) {
              e.printStackTrace();
              break;
         } // catch
    } // while

    try {
         output.close();
         socket.close();
    } catch (Exception e) { 
         System.out.println("Could not close.");
    }
}

Thank you to everyone who may be able to help!

+2  A: 

(1) What's ObjectInputBuffer and ObjectOutputBuffer? Did you mean ObjectInputStream & ObjectOutputStream?

(2) If so, calling reset() immediately after creating the ObjectOutputStream is just a waste of time and bandwidth.

(3) Why are you printing 'could not get an input' on an exception creating an output stream?

(4) When you get an exception you should always print its message - don't completely substitute it with your own, that's just throwing away useful information.

(5) You are assuming that any IOException when reading means the end of the stream. Only EOFException means that. Any other IOException should be printed or logged. Clearly you are getting some other exception here and ignoring it.

(6) Why do you keep sending the same object?

EJP
A: 

From ObjectInputStream API for readUnshared():

Reads an "unshared" object from the ObjectInputStream. This method is identical to readObject, except that it prevents subsequent calls to readObject and readUnshared from returning additional references to the deserialized instance obtained via this call.

Could this be the problem? Use readObject() instead.

Jivings