【问题标题】:Serialized object has null values after being sent via UDP to client in java序列化对象在通过 UDP 发送到 java 中的客户端后具有空值
【发布时间】:2011-12-11 01:08:16
【问题描述】:

这个问题把我逼疯了。这是针对我目前正在开发的非常简单的在线多人游戏。

我目前能够通过 udp 向我的客户发送数据包,而且他们似乎可以正常接收。但是,当我向客户端发送序列化对象并在另一端反序列化时,当我尝试访问所需的值时,我会收到 NullPointerExceptions。我已经验证了对象在服务器端被正确序列化(反序列化并检查数据),所以我 99% 确定我在发送数据包的代码中做错了什么。

下面是从服务器序列化和发送“数据报”对象的代码:

    DatagramPacket sendPacket = null;

    byte[] buf = null;

    //Serialize the datagram object to send as a UDP packet
    try {

        // Serialize to a byte array
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutput out = new ObjectOutputStream(bos);   
        out.writeObject(data);
        buf = bos.toByteArray(); 

        out.close();
        bos.close();

    } catch (IOException e) {
    }

    try {
        sendPacket = new DatagramPacket( buf, buf.length,
                InetAddress.getLocalHost(), 4004);
    } catch (UnknownHostException e){}

    try {
        DatagramSocket sendSocket = new DatagramSocket();
        sendSocket.send( sendPacket );
        changed = true;
    }catch (IOException e) {}

被序列化的“数据”对象充满了正确的值;我很确定。

另一个相关的代码块是客户端的接收块:

public Datagram readDatagram() {

    byte[] buff = new byte[20000];
    DatagramPacket packet = new DatagramPacket(buff, buff.length);
    DatagramSocket receiver = null;

    try {
        receiver = new DatagramSocket(4004);
        receiver.receive(packet);
    } catch (IOException e) {
        System.out.println("ERROR2");
    }

    Datagram data = null;// = new Datagram();

    try {
        // Deserialize from a byte array
        ByteArrayInputStream bis = new ByteArrayInputStream(buff);
        ObjectInput in = new ObjectInputStream(bis);
        data = (Datagram) in.readObject();

        bis.close();
        in.close();
    } catch (ClassNotFoundException e) {
    } catch (IOException e) {
        System.out.println("ERROR3");
    }

    for (int i = 0; i < 35; i++) {
        System.out.print(data.getLevel()[i]);
    }

    receiver.close();

    return data;

}

当我尝试在此反序列化后读取任何值时,我得到 NullPointerException。如果有人能指出我正确的方向,我会非常高兴。

哦,我现在故意发送到 localHost 只是为了测试一下。我的客户端和服务器都在我的机器上运行。

【问题讨论】:

    标签: java serialization client udp


    【解决方案1】:

    在发送端和接收端,您都在捕获和压缩异常。这很有可能隐藏了可以帮助您诊断问题的证据。即使不是这种情况,压制这样的异常也是危险的做法。

    我敢打赌,ClassNotFoundException 会在接收端代码中抛出。这会给你留下data == null,然后会在接下来的循环中导致 NPE。

    【讨论】:

    • 感谢您的提醒。为异常添加了独特的打印输出,但是我仍然没有接近解决这个问题。
    • 您的赌注是正确的。从现在开始,我肯定会听取您的建议,正确处理我的异常。现在,你为什么认为我会得到那个例外?数据报是我创建的一个类,源文件在我的源目录(我在Netbeans)...我什至可以创建它的对象。
    • 你就是那个男人。我追查了这个问题,实际上是通过阅读您的另一篇文章发现了问题。我在服务器端使用 Datagram 类的附加 副本 创建对象,但使用不同的 包名称。我不知道它是如此敏感。
    • 是的。完全限定的类名必须匹配。理想情况下,您应该在客户端和服务器端使用相同的 JAR 文件。
    【解决方案2】:

    您的代码的一个可能问题是您在关闭ObjectOutputStream 之前调用了toByteArray()

    out.writeObject(data);
    buf = bos.toByteArray();
    
    out.close();
    bos.close(); 
    

    如果序列化数据的某些部分直到close() 才写入输出流,在这种情况下它们将丢失。关闭流后尝试调用toByteArray()

    【讨论】:

    • 感谢您的提示,但这并没有解决问题。 @Stephen 是在正确的轨道上,但是我不知道为什么我会得到 ClassNotFoundException ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2013-06-11
    • 2018-08-12
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多