ObjectInputStream 不从输出流中读取所有对象
ObjectInputStream does not read all objects from the output stream
我正在尝试通过套接字将对象从服务器发送到呈现客户端。实体对象的第一个列表由 8 个实体组成,但更多的实体被添加到列表中。我的服务器最终可以将数百个对象写入 ObjectOutputStream,但客户端只读取前 8 个。
我曾尝试在 writeObject 方法之前和之后调用 flush(),但这似乎没有什么不同。我已将问题缩小到客户端。
服务器使用此方法将 ArrayList 写入流:
private void sendEntities() {
try {
ArrayList<Entity> entities = engine.requestEntities();
System.out.println("Entities sent: " + entities.size());
objectOut.writeObject(entities);
// objectOut.flush(); Does not fix the problem
} catch (IOException e) {
e.printStackTrace();
}
}
客户端读取 returns 对象到 setter 方法,将它们绘制在屏幕上,但这是唯一尝试从流中读取对象的区域。
private ArrayList<Entity> requestEntities() {
try {
out.writeUTF("REQ_ENT()");
// The client only receives 8 entity-objects every time
ArrayList<Entity> entitiesReceived = (ArrayList<Entity>) objectIn.readObject();
in.readUTF();
return entitiesReceived;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
我希望从输入流读取的对象列表与写入输出流的对象数量相匹配,但从输入流读取的列表保持不变。它在第一次调用 requestEntities() 时按预期工作,但在后续调用中没有。
编辑:已将 link 添加到 github 存储库
编辑 2:正如 Johannes Kuhn 所指出的,ObjectOutputStream 发送对先前发送的对象的引用。
我添加了一行代码,似乎已经解决了这个问题。我制作了实体列表的副本,并将此副本写入流。
private void sendEntities() {
try {
ArrayList<Entity> entities = engine.requestEntities();
ArrayList<Entity> copy = new ArrayList<>(entities);
System.out.println("Entities sent: " + entities.size());
objectOut.writeObject(copy);
} catch (IOException e) {
e.printStackTrace();
}
}
问题在于 ObjectStreams 会跟踪已发送的对象,而不是再次发送它们,它们只会引用之前的对象。
复制您的 ArrayList 并发送新的 ArrayList。
tl;dr:序列化不是为了 server/client 通信。
我正在尝试通过套接字将对象从服务器发送到呈现客户端。实体对象的第一个列表由 8 个实体组成,但更多的实体被添加到列表中。我的服务器最终可以将数百个对象写入 ObjectOutputStream,但客户端只读取前 8 个。
我曾尝试在 writeObject 方法之前和之后调用 flush(),但这似乎没有什么不同。我已将问题缩小到客户端。
服务器使用此方法将 ArrayList 写入流:
private void sendEntities() {
try {
ArrayList<Entity> entities = engine.requestEntities();
System.out.println("Entities sent: " + entities.size());
objectOut.writeObject(entities);
// objectOut.flush(); Does not fix the problem
} catch (IOException e) {
e.printStackTrace();
}
}
客户端读取 returns 对象到 setter 方法,将它们绘制在屏幕上,但这是唯一尝试从流中读取对象的区域。
private ArrayList<Entity> requestEntities() {
try {
out.writeUTF("REQ_ENT()");
// The client only receives 8 entity-objects every time
ArrayList<Entity> entitiesReceived = (ArrayList<Entity>) objectIn.readObject();
in.readUTF();
return entitiesReceived;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
我希望从输入流读取的对象列表与写入输出流的对象数量相匹配,但从输入流读取的列表保持不变。它在第一次调用 requestEntities() 时按预期工作,但在后续调用中没有。
编辑:已将 link 添加到 github 存储库
编辑 2:正如 Johannes Kuhn 所指出的,ObjectOutputStream 发送对先前发送的对象的引用。 我添加了一行代码,似乎已经解决了这个问题。我制作了实体列表的副本,并将此副本写入流。
private void sendEntities() {
try {
ArrayList<Entity> entities = engine.requestEntities();
ArrayList<Entity> copy = new ArrayList<>(entities);
System.out.println("Entities sent: " + entities.size());
objectOut.writeObject(copy);
} catch (IOException e) {
e.printStackTrace();
}
}
问题在于 ObjectStreams 会跟踪已发送的对象,而不是再次发送它们,它们只会引用之前的对象。
复制您的 ArrayList 并发送新的 ArrayList。
tl;dr:序列化不是为了 server/client 通信。