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

在UDP上发送和接收序列化对象,第1张

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

我最终不知道要完成什么,但是使用UDP并不是那么容易…主要原因是在DatagramPacket对象的说明中:

数据报包用于实现无连接包传递服务。仅基于该数据包中包含的信息,将每条消息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个数据包的路由可能不同,并且可能以任何顺序到达。无法保证数据包的传递。

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

关于您的屏蔽:

从此套接字接收数据报包。当此方法返回时,DatagramPacket的缓冲区将填充收到的数据。数据报数据包还包含发送者的IP地址以及发送者计算机上的端口号。

该方法将阻塞直到接收到数据报。数据报包对象的长度字段包含接收到的消息的长度。如果消息长于数据包的长度,则消息将被截断。

我没有真正测试过,但是根据描述,我很确定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, client, 1234);      socket.send(packet);      // now send the payload      packet = new DatagramPacket(Buf, Buf.length, client, 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类别:

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

获得了byte-To-int
信息)

编辑:如评论中所述,使用UDP通常是一个非常糟糕的主意,主要是因为您不知道是否以正确的顺序接收数据包,甚至根本不接收。UDP不能保证这一点。我没有做太多的udp编程,但是(如果我理解正确的话)您可以依靠的唯一部分是,如果您得到一个数据包并且它适合数据报(65,527字节-
参见https://en.wikipedia .org / wiki /
User_Datagram_Protocol),它将包含整个内容。因此,如果您不关心消息的发送顺序以及对象适合数据报的大小,那应该没问题。

Edit2:至于代码:不要按原样使用它。这只是一个示例,ind
UDP您应该只有一种类型的数据包,并且这种数据包的大小已知。这样,您无需发送“尺寸”。如果您使用上面显示的代码,并且丢弃了一个数据包,则下一个数据包的大小将错误(即,第一个数据包被丢弃,突然您正在检查有效负载的第一个字节以获取大小)。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5428847.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存