Reputation: 582
I'm sending a POJO through a socket in Java using ObjectOutputStream
the POJO is below
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();
}
}
}
I have a Server
and Client
classes, the idea is to create an instance of the Game
class in the server and send it to the client, then perform changes in the data
variable and send it again back and forth between the Server
and the Client
.
The object is being sent but its content is not the expected.
Server Output
Waiting
Connected server
0 0 0
0 0 0
0 0 0
Writing
0 0 0
0 1 0
0 0 0
Expected Output (Client)
Connecting...
Connected client
Reading
0 0 0
0 0 0
0 0 0
Reading
0 0 0
0 1 0
0 0 0
Actual Output (Client)
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
Server class
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);
}
}
Client class
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Client {
public void connect(String host, int port) throws Exception {
System.out.println("Connecting...");
Socket socket = new Socket(host, port);
System.out.println("Connected client");
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
System.out.println("Reading");
Game game1 = (Game) ois.readObject();
game1.printMatrix();
System.out.println("Reading");
Game game2 = (Game) ois.readObject();
game2.printMatrix();
}
public static void main(String[] args) throws Exception {
new Client().connect("localhost", 8082);
}
}
Question
Why if the matrix is being modified in the server when it is sent to the client the client receives the non-modified matrix?
Thanks
Upvotes: 1
Views: 169
Reputation: 147124
Java Serialization can handle cycles all sorts of object graph. It does this by sending back references instead of serialising the object twice.
The second time you are sending the object, you are just sending a reference. You need to either call ObjectOutputStream.reset
the stream, close that stream replacing with another or, best, use immutable value objects. Or either of the first two and last of these - in order to be able to use the back reference the ObjectOutputStream
keeps a reference to all objects sent, and ObjectInputStream
likewise for all objects received.
(You can use ObjectOutputStream.writeUnshared
but that gets even more confusing because the component objects will be shared.)
Stndard warning: Don't use Java Serialization.
Upvotes: 1