加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 在UDP上发送和接收序列化对象

发布时间:2020-12-14 05:44:11 所属栏目:Java 来源:网络整理
导读:我试图使用UDP将一个序列化对象从服务器进程发送到 Java中的客户端进程.问题是客户端正在接收方法被阻止.有人可以帮忙吗? 这里是发送对象的服务器代码: ClientModel C1= new ClientModel(100,"Noor",38,"asd"); ByteArrayOutputStream baos = new ByteArra
我试图使用UDP将一个序列化对象从服务器进程发送到 Java中的客户端进程.问题是客户端正在接收方法被阻止.有人可以帮忙吗?

这里是发送对象的服务器代码:

ClientModel C1= new ClientModel(100,"Noor",38,"asd");
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  ObjectOutputStream oos = new ObjectOutputStream(baos);
  oos.writeObject(C1);
  oos.flush();
  byte[] Buf= baos.toByteArray();
  packet = new DatagramPacket(Buf,Buf.length,client,port);
  socket.send(packet);

这里是接收对象的客户端代码:

byte[] buffer = new byte[100000];
packet = new DatagramPacket(buffer,buffer.length );
socket.receive(packet);
System.out.println("packet received");

我只是希望接收到能够重建的对象,但是我不能收到数据包本身.

解决方法

我不知道你想要完成什么,但是使用UDP不是那么容易…主要原因是在DatagramPacket对象的描述中:

Datagram packets are used to implement
a connectionless packet delivery
service. Each message is routed from
one machine to another based solely
on information contained within that
packet. Multiple packets sent from
one machine to another might be routed
differently,and might arrive in any
order. Packet delivery is not
guaranteed.

使用udp时的一个很好的教程是http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html

关于你的封锁:

Receives a datagram packet from this
socket. When this method returns,the
DatagramPacket’s buffer is filled with
the data received. The datagram packet
also contains the sender’s IP address,
and the port number on the sender’s
machine.

This method blocks until a datagram is
received. The length field of the
datagram packet object contains the
length of the received message. If the
message is longer than the packet’s
length,the message is truncated.

我没有真正测试它,但我非常确定 – 基于描述 – datagramsocket.reseive函数将阻塞,直到数据包被填充(在你的情况下,直到收到100000个字节).

我建议您从具有固定已知长度的数据传送器开始,您可以传输实际有效载荷的大小.就像是:

public static void main(String[] args) {
    ClientModel c1 = new ClientModel ();
    c1.data = 123;
    c1.name = "test";

    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(c1);
      oos.flush();
      // get the byte array of the object
      byte[] Buf= baos.toByteArray();

      int number = Buf.length;;
      byte[] data = new byte[4];

      // int -> byte[]
      for (int i = 0; i < 4; ++i) {
          int shift = i << 3; // i * 8
          data[3-i] = (byte)((number & (0xff << shift)) >>> shift);
      }

      DatagramSocket socket = new DatagramSocket(1233);
      InetAddress client = InetAddress.getByName("localhost");
      DatagramPacket packet = new DatagramPacket(data,4,1234);
      socket.send(packet);

      // now send the payload
      packet = new DatagramPacket(Buf,1234);
      socket.send(packet);

      System.out.println("DONE SENDING");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

在另一边你现在知道你的大小:

public static void main(String[] args) {
    try {
      DatagramSocket socket = new DatagramSocket(1234);

      byte[] data = new byte[4];
      DatagramPacket packet = new DatagramPacket(data,data.length );
      socket.receive(packet);

      int len = 0;
      // byte[] -> int
      for (int i = 0; i < 4; ++i) {
          len |= (data[3-i] & 0xff) << (i << 3);
      }

      // now we know the length of the payload
      byte[] buffer = new byte[len];
      packet = new DatagramPacket(buffer,buffer.length );
      socket.receive(packet);

        ByteArrayInputStream baos = new ByteArrayInputStream(buffer);
      ObjectInputStream oos = new ObjectInputStream(baos);
      ClientModel c1 = (ClientModel)oos.readObject();
      c1.print();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

CientModel clas使用:

public class ClientModel implements Serializable{
    private static final long serialVersionUID = -4507489610617393544L;

    String name = "";
    int data = 1;

    void print() {
        System.out.println(data +": " + name);
    }
}

我测试了这个代码,它的工作原理很好.希望有帮助(我从http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html开始获得字节到int和周围)

编辑:正如注释中所述,主要使用UDP通常是一个非常糟糕的主意,因为您不知道您的数据包是以正确的顺序接收的,甚至是所有的. UDP不保证.我没有做太多的udp编程,但唯一可以依靠的部分(如果我理解的正确)就是,如果你收到一个数据包,它符合数据报(65,527个字节 – 见https://en.wikipedia.org/wiki/User_Datagram_Protocol),它将包含整个事情.所以,如果你不关心消息的顺序和你的对象适合数据报,你应该没事.

编辑2:代码:不要使用它.这只是一个例子,ind UDP你应该只有一种类型的数据包,而且这个数据具有已知的大小.这样你就不需要发送“大小”.如果使用如上所示的代码,并且丢弃一个数据包,则下一个数据包将是错误的大小(即第一个数据包被丢弃,突然间您将检查有效负载的第一个字节以获取大小).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读