Java 缓冲区下溢异常?在这里
我正在用Java编写一个小型UDP服务器。当服务器收到命令(“GET_VIDEO”)时,他读取一个文件(“VIDEO.raw”),然后将其发送给客户端 这是我的密码:Java 缓冲区下溢异常?在这里,java,udp,bufferunderflowexception,Java,Udp,Bufferunderflowexception,我正在用Java编写一个小型UDP服务器。当服务器收到命令(“GET_VIDEO”)时,他读取一个文件(“VIDEO.raw”),然后将其发送给客户端 这是我的密码: public class ServeurBouchon { /** * @param args */ public static void main(String[] args) throws Exception { byte[] buff = new byte[64];
public class ServeurBouchon {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
byte[] buff = new byte[64];
int port = 8080;
DatagramPacket packet = new DatagramPacket(buff, buff.length);
DatagramSocket socket = new DatagramSocket(port);
System.out.println("Server started at 8080 ...");
while (true) {
socket.receive(packet);
new ThreadVideo(socket, packet).run();
}
}
public static class ThreadVideo extends Thread {
private DatagramSocket socket;
private DatagramPacket packet;
public ThreadVideo(DatagramSocket socket, DatagramPacket packet) {
this.packet = packet;
this.socket = socket;
}
public void run() {
String cmd = new String(packet.getData(), 0, packet.getLength());
System.out.println("S:CMD reçu :" + cmd);
if ("GET_VIDEO".equals(cmd)) {
read_and_send_video(this.packet.getAddress());
} else if ("TIMEOUT_REQUEST".equals(cmd)) {
return;
} else {
System.out.println(" Exiting ...");
return;
}
System.out.println("Fin .....");
}
private void read_and_send_video(InetAddress address) {
System.out.println(" reading and sending video ...");
File file = new File("./video/video.raw");
ByteBuffer ibb = ByteBuffer.allocate(4);
ibb.order(ByteOrder.BIG_ENDIAN);
FileInputStream fis = null;
DatagramPacket pack;
byte[] buff = new byte[4];
System.out.println(" Sending ...");
try {
fis = new FileInputStream(file);
int size = 0;
while ( size != -1) {
size = fis.read(buff, 0, buff.length);
System.out.println(" size = " + size);
ibb.put(buff);
System.out.println("Size : " + ibb.getInt());
int length = ibb.getInt();
byte[] fbuff = new byte[length];
fis.read(fbuff, 0, length);
pack = new DatagramPacket(fbuff, fbuff.length, address,
packet.getPort());
socket.send(pack);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
原始文件格式是“大小+帧”的连续格式。“size”变量包含要读取的下一帧的大小(int)。我的问题是,当我读取文件时(在ibb.getInt()行中),我会遇到以下异常:
Exception in thread "main" java.nio.BufferUnderflowException
at java.nio.Buffer.nextGetIndex(Buffer.java:480)
at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:336)
at fr.sar.dss.bouchon.ServeurBouchon$ThreadVideo.read_and_send_video(ServeurBouchon.java:75)
at fr.sar.dss.bouchon.ServeurBouchon$ThreadVideo.run(ServeurBouchon.java:48)
at fr.sar.dss.bouchon.ServeurBouchon.main(ServeurBouchon.java:29)
也许我做错了,但有人能告诉我哪里是我的错吗
谢谢你的帮助;) 读取两个整数
使用以下命令:
int length = ibb.getInt();
System.out.println("Size : " + length);
我终于找到了问题的答案。每次使用ByteBuffer类及其访问方法(如getInt()、getShort()、getFloat()、array())时,都应该调用rewind方法将当前缓冲区位置设置为零。此代码完全有效:
System.out.println("Size : " + ibb.getInt());
ibb.rewind();
int length = ibb.getInt();
ibb.rewind();
谢谢你的帮助你不应该使用倒带。您应该在代码中意识到,每次
获取内容并只读取一次所需的值时,您都在推进字节缓冲区的当前标记。这个答案似乎没有抓住要点。像getInt()这样的方法不会简单地返回典型getter意义上的值。相反,它们返回缓冲区当前位置的值并前进到下一个位置。倒带可能有效(正如您所发现的),但如果在调用getInt()和倒带()之间覆盖了上一个位置,该怎么办?如果您只是想使用多次读取的值,为什么不将其保存到局部变量。对我来说,revind()
帮助解决了这个问题。
System.out.println("Size : " + ibb.getInt());
ibb.rewind();
int length = ibb.getInt();
ibb.rewind();