Java ObjectInputStream不会读取对象?

时间:2014-02-15 15:55:11

标签: java sockets serialization objectinputstream

我遇到了一个问题,我可以连接到我的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();

}

2 个答案:

答案 0 :(得分:0)

您的客户端代码在readObject电话上阻止。它等待直到插槽中的下一个对象可用。虽然您正在服务器套接字上编写该对象,但由于套接字缓冲区,您的客户端将无法立即获取该对象。为了让客户端立即获取对象,您必须在写入每个对象后刷新服务器端的流。在sendNextPacketInQueue方法中,在out.flush()致电后添加out.writeObject来电。

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

答案 1 :(得分:0)

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

甚至不问我是如何犯这些愚蠢的错误的......