Results 1 to 7 of 7
  1. #1
    Wassa is offline Member
    Join Date
    Dec 2008
    Posts
    5
    Rep Power
    0

    Default Sending an object via sockets - all fields but array updating

    I have a client/server multiplayer game application for my final year project at uni.
    The clients connect to the server and choose a game to join.

    Whenever any client who is connected to that game makes a move, all the other clients need to be updated. The server will then send a GameState of the game to all the clients. The client receives the GameState object and handles it suitably.

    The GameState object includes:
    - int playerTurn
    - String gameName
    - Player[] players

    and other relative fields.


    The first time each client receives the GameState object works perfectly fine, everything is as it should be.

    However any further GameState objects that are received do not work so well. All the normal fields variables areas they should be, changing if they need to be. Every single array that is in the GameState object reverts back to the same array that was received the first time round. Whether the array is of type Player/ int / string - it doesnt matter.

    So the client receives the new GameState object with the appropriate values changed apart from all the arrays.

    The server is sending the GameState object with the appropriate values (including the arrays). I had it print out the state that it sent and even write it to a file and in both cases the arrays were as they should be.
    The client also reads in the object from the file several times and the arrays change as they should. The problem only occurs over sockets.

    If I change for datatype, for example:
    instead of int[] numbers being [10,20,30,40,50]
    I have int1 = 10, int2 = 20, etc
    then these values are sent and received correctly, its just when it exists in an array it defaults back to the values that were in the first object.

    Is there something about sending arrays in sockets that I am missing?

  2. #2
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Without seeing your code it's hard to tell precisely what you're doing wrong. But generally, the thing you need to do is just bang the values from the array down the socket, and at the other end, read them in and set them on the client's copy of the array. There's nothing particularly magical. Perhaps if you show us your code?

  3. #3
    Wassa is offline Member
    Join Date
    Dec 2008
    Posts
    5
    Rep Power
    0

    Default

    I made a simple version to replicate the problem. In this case the first object the client receives is correct but then all further objects received are the same as the first.

    Client:
    Java Code:
    package sending;
    
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    
    /**
     * What does class do
     */
    public class Client {
        int port = 6000;
        private ObjectInputStream incoming;
        /** Creates a new instance of Client */
        public Client() {
            try {
                
                Socket s = new Socket(InetAddress.getLocalHost(), port);
                this.incoming = new ObjectInputStream(s.getInputStream());
            } catch (Exception e){
                System.err.println("error");
            }
            
            start();
        }
        
        
        public void start(){
            try {
                while (true){
                    MyObject received = (MyObject) incoming.readObject();
                    received.print();
                }
            } catch (Exception e){
            }
            
        }
        
        
        public static void main(String[] args) {
            Client c = new Client();
        }
    }
    Server:
    Java Code:
    package sending;
    
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     *
     * @author Wassa
     */
    public class Server {
        int port = 6000;
        private ObjectOutputStream outgoing;
        /**
         * Creates a new instance of Server
         */
        public Server() {
            init();
        }
        
        public void init(){
            try {
                ServerSocket serverSocket = new ServerSocket(port);
                Socket clientSocket = serverSocket.accept();
                this.outgoing = new ObjectOutputStream(clientSocket.getOutputStream());
                
                send();
                
            } catch (Exception ex) {
                System.err.println("Server Error");
            }
            
        }
        
        public void send(){
            try {
                MyObject o = new MyObject();
                while(true){
                    Thread.sleep(2000);
                    o.increase();
                    o.print();
                    outgoing.writeObject(o);
                    
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            Server s = new Server();
        }
        
    }
    Object Being Sent:
    Java Code:
    package sending;
    
    import java.io.Serializable;
    
    /**
     * What does class do
     */
    public class MyObject implements Serializable {
        private int intValue;
        private String stringValue;
        private int[] arrayValue = new int[]{10,20,30};
        
        
        /** Creates a new instance of MyObject */
        public MyObject() {
            this.intValue = 0;
            this.stringValue = String.valueOf(intValue);
        }
        
        public void increase(){
            this.intValue = intValue +1;
            this.stringValue = String.valueOf(intValue);
            
            for (int i=0; i<arrayValue.length; i++){
                arrayValue[i] = arrayValue[i] +1;
            }
        }
        
        public int getIntValue() {
            return intValue;
        }
        
        public String getStringValue() {
            return stringValue;
        }
        
        public int[] getArrayValue() {
            return arrayValue;
        }
        
        public void print(){
            System.out.println("=======================");
            System.out.println("INTVALUE: "+intValue);
            System.out.println("STRINGVALUE: "+stringValue);
            for (int i=0; i<arrayValue.length; i++){
                System.out.println("ARRAYVALUE["+i+"]: "+arrayValue[i]);
            }
            System.out.println("=======================");
        }
        
        public static void main(String[] args) {
            MyObject o = new MyObject();
            o.print();
            o.increase();
            o.print();
        }
    }

    Although in this case, none of the values change after the first object is received, all the objects received after that are the same as the first

  4. #4
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    OK, now I see what you're doing. The problem is that you're trying to use the same ObjectOutputStream to write the same object, but midway, you're changing the object's state. ObjectOutputStream isn't designed to do this: when you write the same object multiple times, what it actually sends after the firts time is a "marker" saying "repetition of object X". So at the other end, what you receive is a message effectively saying "the same object as last time was sent", without the changes actually being sent.

    To get round this problem, possibilities include:
    (1) do away with serialization and just write an explicit method to send the bytes/data that you want down the stream
    (2) if you want to use serialization, then each time you need to send an object, create a new ObjectOutputStream around a ByteArrayOutputStream, write the object, then actually send the array from the ByteArrayOutputStream. This way, you're effectively "forgetting" the last version of the object sent down the stream and sending a brand new copy.

  5. #5
    Codapalpjonna is offline Member
    Join Date
    Dec 2008
    Location
    US
    Posts
    2
    Rep Power
    0

    Default alrprpvgjkvqypjsvqjyxvhxmrudrwrferxhello guys need advice

    mmmkwtzbxwtgguonwell, hi admin adn people nice forum indeed. how's life? hope it's introduce branch ;)

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    neil coffey: thanks for the post. As always, it's quite helpful, even for us lurkers.

  7. #7
    Wassa is offline Member
    Join Date
    Dec 2008
    Posts
    5
    Rep Power
    0

Similar Threads

  1. Sending an array in a constructor?
    By dch414 in forum New To Java
    Replies: 2
    Last Post: 09-14-2008, 10:59 PM
  2. Replies: 1
    Last Post: 07-04-2008, 06:39 PM
  3. Sending files over sockets!
    By rameshraj in forum Networking
    Replies: 2
    Last Post: 05-30-2008, 11:18 PM
  4. Sending Mail Using Sockets
    By Java Tip in forum java.net
    Replies: 0
    Last Post: 04-07-2008, 09:05 PM
  5. Problems sending file throught TCP sockets
    By Nite in forum Advanced Java
    Replies: 2
    Last Post: 08-04-2007, 10:01 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •