【问题标题】:Java ObjectInputStream Won't Read Object?Java ObjectInputStream 不会读取对象?
【发布时间】:2014-02-15 15:55:10
【问题描述】:

我遇到了一个问题,我可以连接到我的 ServerSocket 并向我的客户端发送对象(确切地说是自定义 Packet 类),但是当我使用 readObject() 方法时,我的代码挂起并且没有读取任何内容数据包。

这是客户端代码:

public class ObjectReaderThread extends Thread {

public void run() {

    Object obj = null;

    while(!ClientTest.clientTest.socket.isClosed()) {

        try {

            obj = ClientTest.serverReader.reader.readObject();

            System.out.println("Packet recieved.");

        } catch(Exception ex) { ex.printStackTrace(); System.exit(-1); }

    }

}

如您所见,我为 readObject 循环使用了一个单独的线程。有人可以帮我确定什么是不正确的吗?如果需要更多代码,请告诉我,我可以发布它。另请注意,从未给出异常/错误。谢谢!

编辑: 这是发送数据包的代码:

public void sendNextPacketInQueue() {
    Iterator<Integer> queue = packetQueue.keySet().iterator();
    try {

        if(outputStreamInitialized) ;

        if(queue.hasNext()) {

            int key = queue.next();
            Packet packet = packetQueue.get(key);

            if(packet.getLocation().equals(PacketLocation.ALL) && GlobalVars.onlinePlayers.size() > 0) {

                for(int i = 1; i <= GlobalVars.onlinePlayers.size(); i++) {
                    Player player = GlobalVars.onlinePlayers.get(i);
                    ObjectOutputStream out = new ObjectOutputStream(player.getOutputStream());
                        out.writeObject(packet);

                    if(GlobalVars.debugOutput) GlobalClassVars.window.printToLog("Packet sent to " + player.getUsername());
                }
            }
            else {
                if(GlobalVars.debugOutput) GlobalClassVars.window.printToLog("Not enough players online to send packet to.");
            }

            packetQueue.remove(key);
            if(GlobalVars.debugOutput) GlobalClassVars.window.printToLog("Packet removed.");

        }

    } catch(Exception ex) { ex.printStackTrace(); }
}

这是在服务器循环中不断运行的:

while(!serverSocket.isClosed()) {

        ...

        this.sendNextPacketInQueue();

}

【问题讨论】:

  • 向我们展示发送对象的代码。
  • 也许 outputStreamInitialized 是假的。也许队列迭代器中没有任何内容。也许位置不是全部。也许在线播放器的大小为 0(顺便说一下,您的循环是错误的,因为它从 1 开始并以 size 结束,而不是从 0 开始并以 size - 1 结束。这表明我永远不会执行此代码,否则你会得到一个例外)。在您的代码中添加跟踪,或使用您的调试器。此外,您应该为每个发送的对象创建一个新的 ObjectOutputStream。创建一次,然后发送所有对象。
  • 什么意思?读取了一个对象,但没有读取第二个对象?服务器端呢?你检查过那里的一切吗?
  • 是的。但是我让你在服务器端检查了很多东西,你没有提供任何答案。
  • 你知道,但我们不知道。因此,如果您希望我们有效地提供帮助,请告诉我们您所知道的。我们无法猜测。坦率地说,我怀疑发送数据包的循环是否被执行,因为如果是这样,你会得到一个 IndexOutOfBoundsException,因为你的循环不正确。对我来说 EOT。

标签: java sockets serialization objectinputstream


【解决方案1】:

您的客户端代码正在阻止readObject 调用。它一直等到下一个对象在套接字中变得可用。尽管您正在服务器套接字上写入对象,但由于套接字缓冲区,您的客户端不会立即获取它。为了让客户端立即获取对象,您必须在写入每个对象后刷新服务器端的流。在sendNextPacketInQueue 方法中,在out.writeObject 调用之后添加out.flush() 调用。

out.writeObject(packet);
out.flush();

【讨论】:

  • 感谢您的回答,但我已经尝试过了。它不会改变任何东西。
【解决方案2】:

我在这方面做错了很多。首先,我每次都创建一个新的 ObjectOutputStream。其次,我使用 int 而不是用户名从列表中获取玩家。

别问我是怎么犯下这些愚蠢的错误的……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2018-05-20
    • 1970-01-01
    相关资源
    最近更新 更多