java 缓冲区下溢异常?这里?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5261547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BufferUnderflowException? Here?
提问by Dimitri
I am writing a small UDP server in Java. When the server receives a command ('GET_VIDEO'), he reads a file ('video.raw') and then sends it to the client.
我正在用 Java 编写一个小型 UDP 服务器。当服务器收到命令('GET_VIDEO')时,他读取一个文件('video.raw'),然后将其发送给客户端。
Here is my code :
这是我的代码:
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();
}
}
}
}
The raw file format is a continuous of "size + frame". The "size" variable contains the size(an int) of the next frame to be read. My problem is when I am reading the file(in the line ibb.getInt()), I get this exception :
原始文件格式是“大小+帧”的连续格式。“size”变量包含要读取的下一帧的大小(一个整数)。我的问题是,当我读取文件(在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)
Maybe I am doing this wrong but can somebody tells me where is my mistake?
也许我做错了,但有人能告诉我我的错误在哪里吗?
Thansk for your help ;)
谢谢你的帮助;)
回答by Erik
This reads twoints.
这读取两个整数。
System.out.println("Size : " + ibb.getInt());
int length = ibb.getInt();
Use this:
用这个:
int length = ibb.getInt();
System.out.println("Size : " + length);
回答by Dimitri
I finally find the answer to my problem. Everytime you use the class ByteBuffer and his access method (like getInt(), getShort(), getFloat(), array()), you should call the method rewind to set the current buffer position to zero. This code totally works :
我终于找到了我的问题的答案。每次使用 ByteBuffer 类及其访问方法(如 getInt()、getShort()、getFloat()、array())时,都应调用该方法 rewind 将当前缓冲区位置设置为零。这段代码完全有效:
System.out.println("Size : " + ibb.getInt());
ibb.rewind();
int length = ibb.getInt();
ibb.rewind();
Thx for your help
谢谢你的帮助