我不知道你最后想要完成什么,但是使用 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 得到了字节到整数和周围)
编辑:正如 cmets 中所述,使用 UDP 通常是一个非常糟糕的主意,主要是因为您不知道您的数据包是否以正确的顺序接收,甚至根本不知道。 UDP 不保证这一点。我没有做太多的 udp 编程,但你可以依赖的唯一部分(如果我理解正确的话)是,如果你得到一个数据包并且它适合数据报(65,527 字节 - 见https://en.wikipedia.org/wiki/User_Datagram_Protocol)它将包含整个东西。因此,如果您不关心消息的发送顺序并且您的对象适合数据报,那么您应该没问题。
Edit2:至于代码:不要按原样使用。这只是一个例子,在 UDP 中,你应该只有一种类型的数据包,并且这个数据包的大小是已知的。这样你就不需要发送“大小”。如果您使用如上所示的代码,并且丢弃了一个数据包,则下一个数据包的大小将错误(即第一个数据包被丢弃,突然您正在检查有效负载的第一个字节以获取大小)。