2

我想使用 Java 中的 UDP DatagramPacket 将从磁盘读取的视频文件传输到接收器。

关键点如下:虽然要传输的文件是从磁盘读取的,但我应该假设我不知道文件大小。需要增量读取整个文件,并且文件的数据报包应该是不同大小的。

简而言之,我应该假设我正在将实时视频流式传输到接收器,而不知道我完全需要发送多少数据以及数据将以什么速率生成。

现在,我有一个代码可以立即读取磁盘上的文件并转换为数据报包以使用 UDP 套接字进行传输。但是我不知道如何在不知道原始文件大小的情况下将文件打包并逐步读取以模拟视频的实时流。

使用 Java 实现这个想法的任何输入都将非常有用。一旦我得到这个基本的东西,我需要实现一个实时文件传输协议。

发件人:

        File file = new File("/crazy.mp4");
        FileInputStream fis = new FileInputStream(file);
        DatagramPacket pack;


        int size = 0;
        byte[] buffer = new byte[((int) file.length())];
        ByteBuffer bb = ByteBuffer.allocate(4);
        bb.order(ByteOrder.BIG_ENDIAN);

        while (true) {
            size = fis.read(buffer);                
            pack = new DatagramPacket(buffer, buffer.length, address,
                    packet.getPort());
            socket.send(pack);
        }

接收者:

     File file = new File("/crazyRecv.mp4");
     FileOutputStream fos = new FileOutputStream(file);  
     DatagramPacket rpacket = new DatagramPacket(buffer, buffer.length);

        while (true) {
            socket.receive(rpacket);
            fos.write(rpacket.getData(), 0, rpacket.getLength());
        }

谢谢。

4

1 回答 1

2

这段发送和接收 UDP 数据包的代码不能保证在客户端成功地重新创建文件。

  1. UDP 是不可靠的 - 没有像 TCP 那样的低级确认和数据包重传机制,因此您必须实现这一点。数据包可能会丢失并且在客户端永远不会收到
  2. UDP 不是顺序的 - 您不能只期望 UDP 数据包在客户端按顺序接收。第一个数据包可能会先到达最后一个数据包,最后一个数据包会先到达,随后会损坏文件。TCP 保证顺序传递。

如果您仍想使用,您必须编写自己的应用程序级协议。例如

  1. 您发送内容为“文件开始”的数据包
  2. 客户端为该“文件开始:已接收”发送一个确认数据包
  3. 如果您没有收到“文件开始:已收到”,那么您必须转到第 1 步
  4. 然后发送具有唯一 id 的数据包“数据包 1”+数据包数据
  5. 客户端为该“数据包 1:已接收”发送一个 ack 数据包
  6. 如果您没有收到“数据包 1:已收到”,那么您必须转到第 4 步
  7. 对所有数据包执行步骤 4 - 6
  8. 您发送内容为“文件结束”的数据包
  9. 客户端为该“文件结束:已接收”发送一个确认数据包
  10. 如果您没有收到“文件结束:已收到”,那么您必须转到第 8 步
于 2013-04-11T05:27:11.267 回答