0

我已经看过这个问题几次,但老实说我不明白如何让它工作。我有一个客户端和服务器应用程序,服务器有一个 ObjectOutputStream 变量,发送一个包含双整数数组的数组列表(原因是因为它必须发送一个对象,因为普通数组不是对象,我将它包裹在一个数组列表中,以便它能够发送)。客户端通过它的 ObjectInputStream 变量接收它,但它只接收数组列表对象的第一个实例,即使双数组更改了它的编号。我怎样才能让它更新它发送的对象?如何让 ObjectInputStream 每次都接收一个新对象?

-担

服务器:

public class Send extends Thread{
     Starter start;
     PlayerArray array;
     Names name;
     public Send(Starter start, PlayerArray array, Names name){
         this.start = start;
         this.array = array;
         this.name = name;
     }
     public void run(){
         while(start.running){
             for(int i = 0; i < start.roomNum; i++){
                 if(start.send[i] != null && start.OOS[i] != null){
                      try{
                          array.setSendingArray(i);
                          start.OOS[i].writeObject(array.get());
                          start.OOS[i].flush();
                      }catch(Exception e){

                      }
                }
             }
         }
    }
}

服务器播放器数组类:(客户端相同):

public class PlayerArray{
Starter start;
int[][] players;
int[][] sending;
public PlayerArray(Starter start){
    this.start = start;
    players = new int[start.roomNum][2];
    defaultArray();
}
public int[][] getArray(){
    return players;
}
public ArrayList<int[][]> get(){
    ArrayList<int[][]> xyWrap = new ArrayList<int[][]>();
    xyWrap.add(sending);
    return xyWrap;
}
public void set(int[][] xy){
    players = xy;
}
public void set(int index, int newX, int newY){
    players[index][0] = newX;
    players[index][1] = newY;
}
public void setSendingArray(int i){
    //take out "i"'s x and y.
    sending = players;
    //sending[i][0] = -1;
    //sending[i][1] = -1;
}
public void defaultArray(){
    for(int i = 0; i < start.roomNum; i++){
        players[i][0] = -1;
        players[i][1] = -1;
    }
    sending = players;
}

客户:

public class Recieve extends Thread{
Starter start;
PlayerArray array;
Names name;
public Recieve(Starter start, PlayerArray array, Names name){
    this.start = start;
    this.array = array;
    this.name = name;
}
public void run(){
    while(start.running){
        try{
            ArrayList<int[][]> xy = new ArrayList<int[][]>();
            xy = (ArrayList<int[][]>)start.OIS.readObject();
            array.set(xy.get(0));
            int[][] testXY = array.getArray();
            System.out.println("X:  " + testXY[0][0] + "  Y:  " + testXY[0][1]);
        }catch(Exception e){
            System.err.println("CANNOT READ OBJECT!");
        }
    }
}
}
4

1 回答 1

1

当您序列化一个对象时,它会将每个引用替换为一个标记。这意味着如果您两次引用同一个对象或两个对象相互引用,它仍然会正确地(反)序列化对象。

这也意味着

  • 两端都有他们发送或接收的每个对象的缓存,这可能是内存泄漏的原因。
  • 如果您更新对象并再次发送它,它不会“注意到”更改并且您会获得对原始数据的引用。同样,如果您更改反序列化的对象,即使您更改了它,您仍将获得相同的引用。

这两个问题都有一个解决方案,那就是调用reset()ObjectOutputStream。这会清除缓存,防止对象消耗内存并强制它发送任何已发送的对象,以便重新发送。

于 2013-01-27T17:39:28.317 回答