7

Ok so , i have a thread class called 'Client' every time the server accepts a connection it creates a new Client....The run method listens for messages from the client and i am useing ObjectInputStream ..

   do {            
         ObjectInputStream in = null;

        try {
            in = new ObjectInputStream(socket.getInputStream());
            String message = (String) in.readObject();
            System.out.println(message);
            }
            catch (ClassNotFoundException ex) {
                isConnected = false;
                System.out.println("Progoramming Error");
            }
            catch (IOException ex) {
                isConnected = false;
                System.out.println("Server ShutDown");
                System.exit(0);
            }
    } while(isConnected);

The Problem i have is that why do i have to create a new ObjectInputStream every time it loops...and if i close the input stream at the end of the loop and it loops again for another message i will get a error...Please some one help

Mustafa
  • 1,738
  • 2
  • 24
  • 34
  • 2
    You don't have to, and you shouldn't. – JB Nizet Aug 11 '11 at 07:16
  • 1
    And getting a ClassNotFoundException is neither an indication that you are no longer connected nor a programming error. It indicates a *deployment* error. – user207421 Aug 11 '11 at 08:31
  • Could you past what errors are you getting and it would also help if you posted the client code as well. – beny23 Aug 12 '11 at 12:04
  • `isConnected()` is not a valid test for an active connection. The connection is up until you read end of stream, or an `IOException` other than `SocketTimeoutException` occurs. – user207421 Jan 24 '16 at 23:32

2 Answers2

8

Only create the ObjectInputStream once (outside the loop) for a client connection, then put the readObject method into the loop.

Here's a working test class:

public class TestPrg {

    public static void main(String... args) throws IOException {
        ServerListener server = new ServerListener();
        server.start();

        Socket socketToServer = new Socket("localhost", 15000);
        ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());

        for (int i=1; i<10; i++) {
            try {
                Thread.sleep((long) (Math.random()*3000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sending object to server ...");
            outStream.writeObject("test message #"+i);
        }
        System.exit(0);

    }

    static class ServerListener extends Thread {

        private ServerSocket serverSocket;

        ServerListener() throws IOException {
            serverSocket = ServerSocketFactory.getDefault().createServerSocket(15000);
        }

        @Override
        public void run() {
            while (true) {
                try {
                    final Socket socketToClient = serverSocket.accept();
                    ClientHandler clientHandler = new ClientHandler(socketToClient);
                    clientHandler.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class ClientHandler extends Thread{
        private Socket socket;
        ObjectInputStream inputStream;

        ClientHandler(Socket socket) throws IOException {
            this.socket = socket;
            inputStream = new ObjectInputStream(socket.getInputStream());
        }

        @Override
        public void run() {
            while (true) {
                try {
                    Object o = inputStream.readObject();
                    System.out.println("Read object: "+o);
                } catch (IOException e) {
                    e.printStackTrace();

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

In this example Strings are sent trough the ObjectStream. If you get the ClassNotFoundException (http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject()) and are using an independent client and server program than you might check if both the client and the server have the class of the object to send in their class paths.

kvDennis
  • 134
  • 3
  • ohhh i seee ... thanks for that buddy.. i will try it later .. and tell you how it goes.... – Mustafa Aug 11 '11 at 07:59
  • 1
    The sleep is pointless, and the read loop should catch `EOFException` and break out of the reading loop when caught. All other `IOExceptions` except `SocketTimeoutException` are also fatal to the connection and should exit the reading loop. The socket should be closed after the read loop exits for any reason. Too much bad practice here. – user207421 Jan 24 '16 at 23:30
  • Will not the same object be read mutiple times? In the ClientHandler? Or is there some sort of auto-feature inside ObjectInputStream that prevents it from happening? Why would that loop not read same object multiple times? – Lealo Aug 27 '17 at 13:59
  • @Lealo No, the same object will not be read multiple times. Incomprehensible why you would think otherwise. – user207421 Jun 02 '22 at 09:36
-1

The problem i personally had with Sockets and ObjectIOStream, is that it remembers all your object addresses, so each time you send and recive them on the client, if the address of sent object is not changed it will be copied from buffer. So So

  • or create new objects each time you send them ( this is not a bad idiea, because ObjectIOStream seems to has limits on this buffer)
  • or use another Stream for these perpouse
klockvud
  • 99
  • 1
  • 5
  • 1
    Or use `ObjectOutputStream.writeUnshared()`, or `ObjectOutputStream.reset()`. And it has to do with identity hash codes, not addresses. – user207421 Jun 02 '22 at 09:37