缓冲区下溢异常?这里?

3
我正在使用Java编写一个小的UDP服务器。当服务器收到一个命令(“GET_VIDEO”)时,它会读取一个文件(“video.raw”),然后将其发送给客户端。
以下是我的代码:
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类型)。我的问题是当我读取文件时(在< strong>ibb.getInt()行),我收到以下异常:

该段话的意思是:原始文件格式是由“大小+帧”组成的连续数据。其中,“大小”变量包含了下一帧数据的大小(一个整数)。但是,在读取文件时(在代码的< strong>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)

也许我做错了什么,但有人能告诉我我的错误在哪里吗?
谢谢你的帮助 ;)
2个回答

16

这段代码读取了两个整数。

System.out.println("Size : " + ibb.getInt());
int length = ibb.getInt();
请问是否需要上下文?这个内容太短了,不太清楚需要表达什么意思。
int length = ibb.getInt();
System.out.println("Size : " + length);

-3

我终于找到了解决我的问题的方法。每次使用ByteBuffer类及其访问方法(如getInt()、getShort()、getFloat()、array())时,都应该调用rewind方法将当前缓冲区位置设置为零。这段代码完全可行:

    System.out.println("Size : " + ibb.getInt());
    ibb.rewind();
    int length = ibb.getInt();
    ibb.rewind();

感谢您的帮助


2
你不应该使用rewind。在你的代码中,你应该意识到每次你get一些东西并读取你需要的值时,你都会推进字节缓冲区的当前标记。 - Zoltán
1
这个答案似乎没有抓住重点。像getInt()这样的方法并不仅仅是以典型的getter方式返回一个值。相反,它们返回缓冲区当前位置的值并前进到下一个位置。倒带可能有效(正如您所发现的),但如果在调用getInt()和rewind()之间覆盖了先前的位置怎么办?如果您只想使用已读取的值多次,为什么不将其保存到本地变量中呢? - spaaarky21
对我来说,rewind() 帮助我解决了这个问题。 - Akhil Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接