0

I'm writing a server / client game. My client sends a message to the server and the server is supposed to distribute that message to all other clients connected to the server. The problem I'm having is that when I call ois.readObject() (where ois is the ObjectInputStream created from the ServerSocket accept() call) it only ever returns the very first value that I write to the corresponding ObjectOutputStream on the client side.

This is the code for the Thread my server creates for each client that connects.

@Override
public void run() {
    Iterator<ClientThread> itr = null;
    ClientThread ct = null;
    Object recObj = null;
    try {
        oos.writeObject(id);
        oos.flush();

        while(oos != null && ois != null) {
            recObj = ois.readObject();
            System.out.println(recObj);
            if(recObj instanceof Player) {
                System.out.println("[" + id + "] Recieved player from client.");

                player = (Player) recObj;
                Server.playerMap.put(player.getId(), player);

                if(player == null) {
                    System.out.println("Player " + player.getId() + " has joined the server.");
                }

                itr = Server.threadList.iterator();
                while(itr.hasNext()) {
                    ct = itr.next();
                    if(!(ct.id == this.id)) {
                        ct.oos.writeObject(recObj);
                        ct.oos.flush();
                        System.out.println("Sending " + (Player) recObj + " to client " + ct.id + "!");
                    } else {
                        System.out.println("Don't send stuff to " + ct.id + " or we get an infinite loop!");
                    }
                }
            } else {
                System.err.println("Recieved something other than a Player object.");
            }
        }
    } catch (IOException e) {
        System.err.println("[INFO] " + e.getLocalizedMessage());

    } catch (ClassNotFoundException e) {
        System.err.println(e.getLocalizedMessage());
        e.printStackTrace();
    }
    cleanup();
}

This code is for the Thread that each client creates.

@Override
public void run() {
    Object recObj = null;
    Player newPlayer = null;
    try {
        recObj = client.ois.readObject();
        if(recObj instanceof Integer) {
            client.player = new Player((Integer) recObj);
            client.playerMap.put(client.player.getId(), client.player);
        } else {
            System.err.println("First object recieved from server was not of type Integer.");
            System.err.println("No valid id has been set.");
        }

        while(client.ois != null) {
            recObj = client.ois.readObject();
            if(recObj instanceof Player) {
                newPlayer = (Player) recObj;
                System.out.println("Recieved " + newPlayer + "!");
                client.playerMap.put(newPlayer.getId(), newPlayer); 
            }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

P.S. I realize I don't need to flush the ObjectOutputStream but it was just an idea to test.

Rovert Renchirk
  • 97
  • 1
  • 11
  • Not sure if the threading is good this way, I would enqueue the messages for a client in the thread handling that client, but it should basically work in your scenario as well. (hopefully you do not send a new player to a client which not yet has received its id). Your sending whie loop might be blocked by a client not reading, verify it with a println before and after write. – eckes Aug 20 '16 at 14:52

1 Answers1

1

Call .reset on the ObjectOutputStream after each write.

CMPS
  • 7,733
  • 4
  • 28
  • 53
Krrose27
  • 1,026
  • 8
  • 13
  • That worked! But why is it that I need to call reset after each write? – Rovert Renchirk May 05 '12 at 05:03
  • It sends the reset block down the stream and as such the reader should reset for the next object. Without doing it the reader is just seing one large chunk of data. – Krrose27 May 05 '12 at 05:07
  • So then why didn't I have this same issue in another program I had written that I didn't call reset on? Just dumb luck or is it just because of the types of Object that I'm sending through the stream? – Rovert Renchirk May 05 '12 at 05:18
  • Also not sure why reset is needed but if this is a continous process it does not hurt to reset every now and then oherwise the memory with remebered object handles will increment endlessly. – eckes Aug 20 '16 at 14:54
  • @Krrose27 what if calling reset() is increasing the output file size to a large extent. I have arge number of objects to written, assume around 2GB or such. If I call reset() after every write, output size comes out to be 5Gb and that too in around 13 mins or so. Any hack for this? – user3552407 Mar 17 '17 at 14:38