在回答BufferedWriter only works the first time
时出现了这个问题据我所知,Java Doc(网上很多帖子证实了这一点),DatagramPacket不应该接受比当前大小更多的数据。 DatagramSocket.receive的文档说
此方法将一直阻塞,直到收到数据报。数据报包对象的长度字段包含接收消息的长度。如果消息长于数据包的长度,则消息将被截断。
所以,我制作了一个重用接收数据包的程序,并发送更长更长的消息。
public class ReusePacket {
private static class Sender implements Runnable {
public void run() {
try {
DatagramSocket clientSocket = new DatagramSocket();
byte[] buffer = "1234567890abcdefghijklmnopqrstuvwxyz".getBytes("US-ASCII");
InetAddress address = InetAddress.getByName("127.0.0.1");
for (int i = 1; i < buffer.length; i++) {
DatagramPacket mypacket = new DatagramPacket(buffer, i, address, 40000);
clientSocket.send(mypacket);
Thread.sleep(200);
}
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
DatagramSocket serverSock = new DatagramSocket(40000);
byte[] buffer = new byte[100];
DatagramPacket recievedPacket = new DatagramPacket(buffer, buffer.length);
new Thread(new Sender()).start();
while (true) {
serverSock.receive(recievedPacket);
String byteToString = new String(recievedPacket.getData(), 0, recievedPacket.getLength(), "US-ASCII");
System.err.println("Length " + recievedPacket.getLength() + " data " + byteToString);
}
}
}
输出
Length 1 data 1
Length 2 data 12
Length 3 data 123
Length 4 data 1234
Length 5 data 12345
Length 6 data 123456
...
因此,即使长度为1,对于下一次接收,它也会获得长度为2的消息,并且不会截断它。但是,如果我手动设置包的长度,则消息将被截断为此长度。
我在OSX 10.7.2(Java 1.6.0_29)和Solaris 10(Java 1.6.0_21)上测试了这个。所以我的问题。
为什么我的代码可以运行并且可以期望它在其他系统上运行?
澄清一下,这种行为似乎在过去的某个时候发生过变化(至少对于某些JVM而言),但我不知道旧的行为是否是一个错误。我很幸运它以这种方式工作,我是否应该期望它在Oracle JVM,IBM JVM,JRockit,Android,AIX等上以相同的方式工作?
在进一步调查并检查1.3.0,1.3.1和1.4.0的源代码之后,从1.4.0开始在Sun实现中引入了更改,但是在发行说明或网络中没有提到这一点。 JDK 1.4.0的特定发行说明。
答案 0 :(得分:6)
这里有两种不同的长度。在构造函数中,数据包的长度设置为100:
DatagramPacket recievedPacket = new DatagramPacket(buffer, buffer.length);
根据文档,length()
方法告诉您当前存储在数据包中的消息的长度。改变
byte[] buffer = new byte[100];
到
byte[] buffer = new byte[10];
提供以下输出:
Length 1 data 1
Length 2 data 12
...
Length 9 data 123456789
Length 10 data 1234567890
Length 10 data 1234567890
Length 10 data 1234567890
...