Anton Giertli
Anton Giertli

Reputation: 936

Java client app freezes when sending object through sockets

i have this client/server application, and the client application sometimes completely freezes when i try send object via sockets

public Client client = new Client();
petriNetList = client.query(client.actionLoadPetriNetList, MainWindow.loginUsername);

here is the code of the client

 public class Client {
    public static Socket kkSocket = null;
    public static PrintWriter out = null;
    public static BufferedReader in = null;
    public static BufferedReader stdIn = null;
    public static OutputStream outputStream = null ;
    public static ObjectOutputStream  objectOutputStream = null ; 
    public static InputStream inputStream = null ; 
    public static ObjectInputStream  objectInputStream = null ;  


    public String actionSavePetriNet = "SAVE PETRI NET START";



    /*
     * Save petri net to server
     * 
     * @param action identifies query
     * @param petriName name of the petri net
     * @param username username
     * @param xml content of the petri net
     * 
     * @return int response form server
     */
public int query (String action,String petriName,String username,String xml) throws IOException {



    int size ;
    int result = 0;
    connect();
    if (action.equals(actionSavePetriNet)) {

        out.println(action); // save petri net
        out.println(petriName); //petri net name
        out.println(username); //username
        System.out.println("(Client:)" + xml);
        objectOutputStream.writeObject(xml); //send object over the network
        System.out.println("Dostali sme sa sem ?");
        result = Integer.parseInt(in.readLine()); //read response from server
    }

       disconnect();
        return result;
}    


    /*
     * connect to server
     * TODO: ADD hostname and port as parameter
     */
    public static void connect() throws IOException {
    try {
            kkSocket = new Socket("osiris-PC", 4444);
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: taranis.");
            System.exit(1);
        }

         stdIn = new BufferedReader(new InputStreamReader(System.in));

          outputStream = kkSocket.getOutputStream();  
          objectOutputStream = new ObjectOutputStream(outputStream);  

          inputStream = kkSocket.getInputStream();
          objectInputStream = new ObjectInputStream(inputStream);

    }

    /*
     * Disconnect from server
     * close all input/output streams
     * 
     */
    public static void disconnect() throws IOException {
        out.close();
        in.close();
        stdIn.close();
        objectOutputStream.close();
        outputStream.close();
        objectInputStream.close();
        inputStream.close();
        kkSocket.close();

    }
}

and this is the code of server

public class PetriServer {
    public static Protocol kkp = new Protocol();

    public static   InputStream inputStream = null ;
    public static   ObjectInputStream objectInputStream = null ; 
    public static   OutputStream outputStream = null ;
    public static   ObjectOutputStream objectOutputStream = null ;



    public static void main(String[] args) throws IOException, ClassNotFoundException {
        kkp.loadUsers();

     while(true) {
         ServerSocket serverSocket = null;

            inputStream = null ;
            objectInputStream = null ; 
            outputStream = null ;
            objectOutputStream = null ;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                clientSocket.getInputStream()));

        inputStream = clientSocket.getInputStream();  
       objectInputStream = new ObjectInputStream(inputStream);  

        outputStream = clientSocket.getOutputStream();
       objectOutputStream = new ObjectOutputStream(outputStream);
       inputLine = in.readLine();

        String inputLine;
 if (inputLine.equals("SAVE PETRI NET START")) {

            String petriName;
            String username;
            String xml ;
            String input;
            int result;
            int size ;

            petriName = in.readLine(); //read petri name

            System.out.println("(Server): prijali sme poziadavok na ulozenie " + petriName );


            username = in.readLine(); //read username
            System.out.println("(Server): poziadavok ide od usera: " + username);

          while(true) {

//this is the line where is occasionally freezes 
                xml = (String)objectInputStream.readObject(); //read object over the network
           if (!xml.isEmpty()) break; 
          }


          System.out.println("(Server):" + xml);

            result = kkp.savePetrinet(username, petriName,xml); //save it to the file
            out.println(result);

        }

        out.close();
        in.close();
        objectInputStream.close();
        inputStream.close();
        objectOutputStream.close();
        outputStream.close();
        clientSocket.close();
        serverSocket.close();


    }
    }
}

Does anybody know what can be problem ? cheers.

Upvotes: 1

Views: 1433

Answers (1)

John Haager
John Haager

Reputation: 2115

You have the Socket InputStream on the server attached to two different inputs, ObjectInputStream and BufferedReader. InputStreams are not intended to be used this way, and doing so can cause a lot of problems. BufferedReaders, by their nature, are going to be pulling more data off the InputStream than you are actually reading. If they happen to buffer data that makes up an object, then your subsequent attempt to read the object off the ObjectInputStream will block, because the data has already been removed.

You need to pick one method or the other to read data. If you need to be able to read both Strings and Objects off the Socket, then you will have to go to a byte-oriented mode of operation where you read the bytes off into a byte array, then process the byte array yourself to insure that you don't loose any data.

Edit based on @Dunes comment below

Seems your best bet is to stick entirely with ObjectInputStream and make use of its other methods that allow you to read arbitrary primitive types from the stream. And, if you don't mind the deprecated call, it even has a readLine method.

Upvotes: 1

Related Questions