【问题标题】:Java Receiving Java Objects as a Datagram PacketJava 接收作为数据报包的 Java 对象
【发布时间】:2012-10-08 13:32:35
【问题描述】:

我想以 UDP 数据包的形式发送一个对象,然后在服务器上接收该对象。我已经弄清楚客户端,但我无法让服务器正确读取数据报。

客户代码:

public void sendMessage() {
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();

        try {
            ObjectOutput oo = new ObjectOutputStream(bStream);
            oo.writeObject(asset);
            // Send it

            byte[] serializedMessage = bStream.toByteArray();

            DatagramPacket sendPacket = new DatagramPacket(serializedMessage,
                    serializedMessage.length, ipAddress, sPort);
            clientSocket.send(sendPacket);
            oo.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

服务器尝试失败。

public void startServer() {
    try {
         serverSocket = new DatagramSocket(this.serverPort);
         serverSocket.receive(new DatagramPacket()); /*Code fails here, I realise
         * the constructor does not have input, but I can not figure out how to init
         *a buffer whose size I do not know beforehand.
         */
       this.threadPool.execute(new QueryTask(packet));
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
        }
}

我使用以下问题Sending Objects Across Network using UDP in Java发送对象,但没有显示他是如何收到该对象的。

问题 2: 收到并解析数据包后创建一个新线程更好,还是应该在 Datagrampacket 上使用 DatagramSocket 创建一个新线程?

提前致谢。

【问题讨论】:

标签: java network-programming udp threadpool


【解决方案1】:

正如您已经看到的,数据报包需要缓冲区来写入内容。我会创建一个足够大的缓冲区来存储意图数据(UDP 为 IPV4 指定 65K,为 IPV6 指定 4G)。如果我是你,我不会使用 java.io 序列化,因为它会在每次类更改(甚至有时编译器更改)时中断。使用更健壮的序列化方式,例如 JSON(使用 jackson / gson)或 XML 或 protobuf

【讨论】:

  • UDP 没有“为 UDP 指定 65K”。 IPv4 UDP 有效负载的最大大小为 65535-20-8=65507 字节。 Java 对象序列化不会“在每次类更改时中断”,除非您管理不善
  • 有时它会在编译器更改时中断,并且性能并不令人印象深刻。
  • 'Sometimes' 不等于'every class change',是吗?
  • 是的,我的服务器在重建对象时破坏了它。似乎无法获取抽象基类中的变量,但具体类中的所有变量都显示出来了:(
  • 抽象基类必须也可以序列化到最后一个海龟,双方都应使用相同的编译器等进行编译 - 抓住 gson、jackson 或 protobuf 并将您的数据编组为一些可移植格式。跨度>
【解决方案2】:

创建一个比您预期接收的最大数据包大一号的缓冲区。然后,如果你得到一个这么大的数据包,那就是溢出了。请注意,您应该在每次接收之前重新初始化 DatagramPacket 的长度,否则它会一直缩小到目前接收到的最小数据报。

如果您可以足够快地处理数据包,那么您根本不需要使用 UDP 的线程,就没有要处理的连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2015-10-09
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    相关资源
    最近更新 更多