我正在使用ObjectOutputStream
通过Java中的套接字发送POJO,该POJO在下面
import java.io.Serializable;
public class Game implements Serializable {
private static final long serialVersionUID = 4367518221873521320L;
private int[][] data = new int[3][3];
Game() {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
data[x][y] = 0;
}
}
}
int[][] getData() {
return data;
}
public void setData(int[][] data) {
this.data = data;
}
void printMatrix() {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
System.out.print(data[x][y] + " ");
}
System.out.println();
}
}
}
我有一个Server
和Client
类,其想法是在服务器中创建Game
类的实例并将其发送给客户端,然后在{ {1}}变量,然后在data
和Server
之间来回发送。
正在发送对象,但其内容不是预期的。
服务器输出
Client
预期产量(客户)
Waiting
Connected server
0 0 0
0 0 0
0 0 0
Writing
0 0 0
0 1 0
0 0 0
实际输出(客户)
Connecting...
Connected client
Reading
0 0 0
0 0 0
0 0 0
Reading
0 0 0
0 1 0
0 0 0
服务器类
Connecting...
Connected client
Reading
0 0 0
0 0 0
0 0 0
Reading
0 0 0
0 0 0 #<-- there is no 1
0 0 0
客户端类
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
void start(int port) throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Waiting");
Socket socket = serverSocket.accept();
System.out.println("Connected server");
Game game = new Game();
game.printMatrix();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
System.out.println("Writing");
oos.writeObject(game);
game.getData()[1][1] = 1;
game.printMatrix();
oos.writeObject(game);
}
public static void main(String[] args) throws Exception {
new Server().start(8082);
}
}
问题
为什么在将矩阵发送给客户端时,如果正在服务器中对矩阵进行修改,则客户端会收到未修改的矩阵?
谢谢
答案 0 :(得分:1)
Java序列化可以处理各种对象图的循环。它通过发送回引用而不是序列化对象两次来实现此目的。
第二次发送对象时,您只是在发送引用。您需要调用ObjectOutputStream.reset
流,用另一个关闭流,或者最好使用不可变值对象。或其中的前两个和后一个-为了能够使用向后引用,ObjectOutputStream
保留对所有发送对象的引用,ObjectInputStream
则同样对接收到的所有对象进行引用。
(您可以使用ObjectOutputStream.writeUnshared
,但由于组件对象将被共享,这会更加令人困惑。)
标准警告:请勿使用Java序列化。