-1

i'm writing (testing) a simple client-server application where i need to send some object via socket's ObjectOutputStream and next read it via socket't ObjectInputStream. The problem is that the ObjectOutputStream writeObject method doesn't work properly (or maybe i'm doing something wrong ...). I'm doing writing and reading in the same method.

java -version:

java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

This is my code:

ServerTest.java

ExecutorService tp = Executors.newFixedThreadPool(2);
public ServerTest(String info) {
    System.out.println("SERVER TEST HAVE BEEN STARTED FROM " + info);
    try {
        System.out.println("Starting server ...");
        tp.submit(new ServerTask());
        System.out.println("Server started ...");
        Thread.sleep(1000);
        System.out.println("Starting client ...");
        tp.submit(new Client(new Socket("localhost", 3333)));
        System.out.println("Client started at localhost on port 3333 ...");
    } catch (IOException | InterruptedException ex) {
        Logger.getLogger(ServerTest.class.getName()).log(Level.SEVERE, null, ex);
    } 
}
public static void main(String[] args) {
    try {
        new ServerTest("SERVER TEST MAIN STATIC METHOD");
        Thread.sleep(100000);
    } catch (InterruptedException ex) {
        Logger.getLogger(ServerTest.class.getName()).log(Level.SEVERE, null, ex);
    }
}

ClientTask.java (implements Runnable )

private Socket socket;
private ObjectOutputStream oos;
private ObjectInputStream ois;    
public ClientTask(Socket socket) {
    System.out.println("CLIENT TASK SOCKET : " + socket);
    this.socket = socket;
    try {
        oos = new ObjectOutputStream(socket.getOutputStream());
        oos.flush();
        ois = new ObjectInputStream(socket.getInputStream());
    } catch (IOException ex) {
        Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void run() {
    System.out.println("client task running ...");
    for (int i = 0; i < 1; i++) {
        try {
            Thread.sleep(1000);
            SimpleObject so = new SimpleObject(100, "test_str");
            System.out.println("Trying to serialize object into output stream...");
            System.out.println("Object to be written " + so.toString());
            oos.writeObject(so);
            oos.flush();
            System.out.println("Check if the object had been serialized properly ...");
            System.out.println("Bytes in stream : " + ois.available());
            if (ois.available() <= 0) {
                System.out.println("Object had not been serialized ...");
                continue;
            }
            System.out.println("Trying to deserialize object from input stream ...");
            SimpleObject desObj = (SimpleObject) ois.readObject();
            System.out.println("Read object: " + desObj.toString());
            System.out.println("Aborting from method ...");
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                ois.close();
                oos.close();
            } catch (IOException ex) {
                Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    System.out.println("Exiting client task ...");
}

ServerTask.java (implements Runnable)

ExecutorService tp = Executors.newFixedThreadPool(10);
@Override
public void run() {
    System.out.println("Server task run start ...");
    try {
        ServerSocket ss = new ServerSocket(3333);
        for (;;) {
            System.out.println("Server socket start ...");
            Socket s = ss.accept();
            s.setSoTimeout(0);
            System.out.println("Connection: " + s.getInetAddress().toString() + " " + s.getPort());
            System.out.println("Starting client task ...");
            tp.submit(new ClientTask(s));
            System.out.println("Client task started ...");
            System.out.println("Server socket end ...");
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    System.out.println("Server task run end ...");
}

Client.java (implements Runnable)

private Socket socket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
public Client(Socket socket) {
    System.out.println("CLIENT SOCKET : " + socket.toString());
    this.socket = socket;
    try {
        oos = new ObjectOutputStream(socket.getOutputStream());
        oos.flush();
        ois = new ObjectInputStream(socket.getInputStream());
    } catch (IOException ex) {
        Logger.getLogger(ClientTask.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void run() {
    for (int i = 0; i < 10; i++) {
        //System.out.println("client running ...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

SimpleObject.java (implements Serializable)

private static final long serialVersionUID = 4L;
private Integer integer;
private String string;
public SimpleObject(Integer integer, String string) {
    this.integer = integer;
    this.string = string;
}
//getters,setters, toString method ...

The output is

run:
SERVER TEST HAVE BEEN STARTED FROM SERVER TEST MAIN STATIC METHOD
Starting server ...
Server started ...
Server task run start ...
Server socket start ...
Starting client ...
CLIENT SOCKET : Socket[addr=localhost/127.0.0.1,port=3333,localport=57703]
Connection: /127.0.0.1 57703
Starting client task ...
CLIENT TASK SOCKET : Socket[addr=/127.0.0.1,port=57703,localport=3333]
Client started at localhost on port 3333 ...
Client task started ...
Server socket end ...
Server socket start ...
client task running ...
Trying to serialize object into output stream...
Object to be written SimpleObject{integer=100, string=test_str}
Check if the object had been serialized properly ...
Bytes in stream : 0
Object had not been serialized ...
Exiting client task ...

It's a simple application but it doesn't work ... i can't understand why. Please help me.

Robert
  • 46
  • 8
  • Does your object `SimpleObject` implements Serializable interface. – vavasthi Mar 25 '19 at 14:46
  • @VinayAvasthi yes. – Robert Mar 25 '19 at 14:51
  • The line System.out.println("Bytes in stream : " + ois.available());, which is showing the bytes of the input stream of the Socket of the client task. That will show a count of available bytes sent by the server, which won't have anything to do with what was written to the socket output stream. – Thomas Bitonti Mar 25 '19 at 15:53
  • Also, do you want both the client and the server to be using the same input streams? I would expect the client and server to be on different threads (or, in different java processes), in which case the client output stream would map to the server input stream and the client input stream would map to the server output stream. Here is a good example to follow: https://www.baeldung.com/a-guide-to-java-sockets (Note: This is not meant to endorse Baeldun. But the example is good.) – Thomas Bitonti Mar 25 '19 at 15:57
  • @ThomasBitonti i wrote both writing and reading of object into one method just for easier testing ... but now, i tried to split it into different threads (and classes) and it works. Thank you very much, if you post your comment as answer i'll mark it as accepted answer. – Robert Mar 25 '19 at 16:23
  • `available()` does not provide a 'count of bytes sent by the server'. It provides the number of bytes that are *currently* available to be read *without blocking.* A value of zero does *not* mean an object wasn't serialized properly: a positive valueless *not* mean it was; and a negative value is impossible. Regardless of where it came from. @ThomasBitonti – user207421 Mar 25 '19 at 16:34
  • Yes; but the main point was more that the input and output streams weren't attached to each other. Data fed to the client output stream isn't available in the client input stream (unless, say, the server feeds the data back to the client.) – Thomas Bitonti Mar 25 '19 at 18:08

1 Answers1

0

Do you want both the client and the server to be using the same input streams? I would expect the client and server to be on different threads (or, in different java processes), in which case the client output stream would map to the server input stream and the client input stream would map to the server output stream. Here is a good example to follow: baeldung.com/a-guide-to-java-sockets (Note: This is not meant to endorse Baeldun. But the example is good.)

Thomas Bitonti
  • 1,179
  • 7
  • 14