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();
    }
}

Link to github repository

问题在于 ObjectStreams 会跟踪已发送的对象,而不是再次发送它们,它们只会引用之前的对象。

复制您的 ArrayList 并发送新的 ArrayList。

tl;dr:序列化不是为了 server/client 通信。