我最终不知道要完成什么,但是使用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您应该只有一种类型的数据包,并且这种数据包的大小已知。这样,您无需发送“尺寸”。如果您使用上面显示的代码,并且丢弃了一个数据包,则下一个数据包的大小将错误(即,第一个数据包被丢弃,突然您正在检查有效负载的第一个字节以获取大小)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)