Search code examples
javasocketsserversocket

Sending ArrayList from server side to client side using TCP over socket


I'm trying to send an Object from Server Side to Client Side but i can't find the problem. Here is the error I'm getting on the Client side:

java.io.StreamCorruptedException: invalid type code: 43
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at connection.MainClient.doAll(MainClient.java:56)
at connection.TestScreen$2.actionPerformed(TestScreen.java:82)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Here below is the Server Side method: The seperate method in the Infinite loop is just reading from a file and parsing the Usernames and passwords to ArrayList that are instance variables in the Server class.

    public void doStuff() throws Exception
{
    ServerSocket serverSocket = new ServerSocket(5001);
    Socket clientSocket = serverSocket.accept();
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
            new InputStreamReader(
            clientSocket.getInputStream()));
    ObjectOutputStream objectOutput = new ObjectOutputStream(clientSocket.getOutputStream());
    String inputLine;
    out.println("Connected");
    while(true)
    {
        seperate();
        while ((inputLine = in.readLine()) != null) 
        {
            if(inputLine.equalsIgnoreCase("users"))
                objectOutput.writeObject(getUserNames());
            else
                if(inputLine.equalsIgnoreCase("pass"))
                    objectOutput.writeObject(getPassWords());
                else
                    if(inputLine.equalsIgnoreCase("stop"))
                        objectOutput.reset();
        }
    }
}

Here below is the client side requesting the info from the server:

public boolean doAll(String name, String pass) throws Exception
{
    try 
    {
        kkSocket = new Socket("PC", 5001);
        out = new PrintWriter(kkSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
    } 
    catch (UnknownHostException e) 
    {
        System.err.println("Don't know about host: PC.");
        System.exit(1);
    }
    catch (IOException e) 
    {
        System.err.println("Couldn't get I/O for the connection to: PC.");
        System.exit(1);
    }

    ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream());

    out.println("user");
    Object obj = objectInput.readObject();
    users = (ArrayList<String>)obj;
    out.println("pass");
    obj = objectInput.readObject();
    this.pass = (ArrayList<String>)obj;
    out.println("stop");
    objectInput.close();
    out.close();
    in.close();
    kkSocket.close();

    if(userIsRegistered(name,pass))
        return true;
    return false;
}

I am new at learning Server sockets and sockets but what i am trying to accomplish here is this. When I press a button in another class I do this:

MainClient b = new MainClient();
login = b.doAll(userField.getText(),passField.getText());
Login is obviously a boolean.

Pretty much a login system over server to cleint where when the login button is pressed it invokes a client to connect to this server and get the list of Users and Passes on the server that is stored in a text file in the specified directory. Then when the client recieves this information it checks if it could possibly be a user from the Strings i get form the two text fields and returns true or false. Then closes the socket to the server and it should just keep reconnecting everytime right ?

My main problem is how do you fix the error it keeps throwing ?


Solution

  • The flow of your code is as follows:

    1. Server started and waiting for connection with client
    2. Server accepts a connection from a client using serverSocket.accept().
    3. Server sends a String message("Connected") to client using PrintWriter object via out.println("Connected").
    4. Client is reading that message using ObjectInputStream object which is leading to stream mismatch and hence violating the internal consistency checks.That's why StreamCorruptedException is thrown at client side.So Instead of using ObjectInputStream to read the plain message sent by server you should use BufferedReader object that you had created above.

    So at client side your code should be modified to:

    ObjectInputStream objectInput = new ObjectInputStream(kkSocket.getInputStream());
    String message = in.readLine();//use BufferedReader to read the plain message coming from Server.
    System.out.println("Message from server: "+message);
    out.println("user");
    Object obj = objectInput.readObject();