【发布时间】:2019-12-12 10:29:12
【问题描述】:
我正在尝试通过套接字将对象从服务器发送到渲染客户端。第一个实体对象列表由 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();
}
}
客户端读取对象并将其返回给在屏幕上绘制对象的 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() 时按预期工作,但在后续调用时不会。
编辑:已添加到 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();
}
}
【问题讨论】:
-
我认为您在向我们展示的代码之外的某个地方存在错误。您对 ObjectInputStream/ObjectOutputStream 的期望是正确的,这里贴出的代码没有明显的问题。
-
我尝试将其保留在造成问题的部分,但我可以发布 github 链接以进行进一步检查。
-
如果您继续发送相同的列表,您将得到相同的列表,没有任何变化。始终发送新副本。
-
你为什么打电话。
readUTF(),并在你没有调用writeUTF()的时候把结果扔掉? -
我使用 writeUTF 从服务器请求不同的元素,我曾经使用 readUTF 进行响应(主要是测试套接字通信);但既然你提到它,它似乎是多余的。
标签: java sockets objectinputstream objectoutputstream