Search code examples
javasocketsobjectinputstreamobjectoutputstream

can't instantiate ObjectInputStream to read input from user


I can't add a ObjectInputStream to read input from the user, it always blocks at that point. This code works fine if I remove the ObjectInputStream in the Server that is supposed to read input from user and then send hardcoded String instead. What is happening behind the scenes? I'am aware that when a ObjectOutputStream is created it sends a header and when a ObjectInputStream is created it reads that header. Do I need to flush something in System before I try to instantiate oOISUser?

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public Server() {
        ServerSocket oSS = null;
        Socket oS = null;
        ObjectOutputStream oOOS = null; // to write to socket
        ObjectInputStream oOIS = null; // to read from socket
        ObjectInputStream oOISUser = null; // to read input from user

        try {
            oSS = new ServerSocket(1025);
            oS = oSS.accept();
            oOOS = new ObjectOutputStream(oS.getOutputStream());
            oOIS = new ObjectInputStream(oS.getInputStream());
            oOISUser = new ObjectInputStream(System.in);`// doesn't get past this

            String sToSend = (String) oOISUser.readObject();
            System.out.println("server says: " + sToSend);
            oOOS.writeObject(sToSend);
            oOOS.flush();
            System.out.println("server receives: " + (String) oOIS.readObject());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (oSS != null) oSS.close();
                if (oS != null) oS.close();
                if (oOOS != null) oOOS.close();
                if (oOIS != null) oOIS.close();
                if (oOISUser != null) oOISUser.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    public static void main(String[] args) {
        Server s = new Server();
    }
}

This is the code for the Client:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Client {
    public Client() {
        Socket oS = null;
        ObjectOutputStream oOOS = null;
        ObjectInputStream oOIS = null;

        try {
            oS = new Socket("127.0.0.1", 1025);
            oOOS = new ObjectOutputStream(oS.getOutputStream());
            oOIS = new ObjectInputStream(oS.getInputStream());

            System.out.println("client receives: " + (String) oOIS.readObject());
            String sToSend = "hello from client";
            System.out.println("client says: " + sToSend);
            oOOS.writeObject(sToSend);
            oOOS.flush();

        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                if (oS != null) oS.close();
                if (oOOS != null) oOOS.close();
                if (oOIS != null) oOIS.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        Client c = new Client();
    }

}

Solution

  • new ObjectInputStream(System.in)
    

    You said it yourself in the question:

    when a ObjectInputStream is created it reads that header

    So you're effectively waiting for the user to enter an ObjectInputStream header in the console. That has a very very tiny chance to happen (unless a file is piped to System.in). It just makes very little sense to read serialized Java objects from System.in. The user can't possibly type valid serialized Java objets in the console. He/She can type text, though. So use a Reader or a Scanner.