【问题标题】:About uploading mp3 files from clients to the server using UDP关于使用 UDP 从客户端上传 mp3 文件到服务器
【发布时间】:2020-09-09 01:27:19
【问题描述】:

我是 StackOverflow 的新手,如果我的问题被问得不恰当或令人困惑,请告诉我,谢谢!

我正在处理一个音频流项目,其中允许客户端将他们的 mp3 文件上传到服务器。服务器会将它们存储到播放列表中,并将歌曲流式传输回所有客户端。 这是我的客户端上传 mp3 的代码:

    public static void sendPackets(){
        System.out.println("Sending test file...");
        try{
            while (active){
                //The song needs to be uploaded;
                File file = new File("Sorrow.mp3") 
                FileInputStream fis = new FileInputStream(file);
                byte[] byteStream = new byte[(int) file.length()]; 
                //Trying to convert mp3 to byteStream
                fis.close();
                InetAddress destination = InetAddress.getByName("localhost");
                DatagramPacket sendingAirMail = new DatagramPacket(byteStream, byteStream.length, destination, 50010); // 50010 is the listening port
                serverSocket.send(sendingAirMail); // sending the entire bytestream via UDP
                // ServerSocket is a DatagramSocket
                break;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

问题出在这里:

serverSocket.send(sendingAirMail);

因为它会给我这个错误:

java.net.SocketException: The message is larger than the maximum supported by the underlying transport: Datagram send failed
    at java.base/java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
    at java.base/java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:136)
    at java.base/java.net.DatagramSocket.send(DatagramSocket.java:695)
    at client.sendPackets(client.java:116)
    at client$2.run(client.java:67)

查了google才知道是因为UDP在每一个投递的包里都有大小限制,所以想知道这种情况下如何正确分离UDP包?我知道在这种情况下 TCP 会更好,但我认为我需要学习如何分离包,因为我需要使用 UDP 从服务器流回字节数组。任何帮助将不胜感激!

如果需要,我可以发布我的服务器和其他客户端信息。

【问题讨论】:

  • 您知道 UDP 不能保证可靠,不是吗?你有没有想过如果一个数据包没有送达你会怎么做,这意味着你的文件丢失了一大块,并可能导致文件损坏。
  • 我知道,但是我以后仍然需要 UDP 来传输音频,而且我无法在一个数据包中传输整个音频。我可能会将音频上传协议更改为 TCP,但我想我仍然需要了解如何分离包以使用 UDP 进行流式传输。如果我有更好的音频传输方式,请告诉我,谢谢!

标签: java udp client-server mp3


【解决方案1】:

问题是您需要将文件分成几部分并交付它们。对于 UDP,您需要一些东西来确保文件完整且正确。以下是一些建议:

首先,你需要剪切你的文件,所以你需要在头部给出一个 seq 标志。此外,您可能需要一些额外的信息,例如文件的整体大小、时间戳等。

struct msg {
    int seq;
    int total_seq;
    int size;
    void *data;
};

那么,最好建立一个发送缓冲区和接收缓冲区,每次检查缓冲区是否为空,如果不是,发送/接收它。

收到一些片段后,您需要使用 seq 标志重建它们。当某些 seq 丢失时,您需要重新传输。所以这里需要重传设计。

总之,你至少需要以下几样东西:

  1. 信息前用户定义的头部
  2. 剪切/重建文件
  3. 重传(GBN 或 FEC 或两者)

希望对你有帮助。

【讨论】:

  • 谢谢!我也想知道是否有任何图书馆可以让这更容易?如果没有,我应该寻找哪个库来创建用户定义的头部?我应该使用什么库来从 UDP 包中收集信息?
  • 是的,github上有很多开源项目。但是它们不容易阅读或复制,例如QUIC、KCP、libutp。
  • 至于自定义头部,其实很简单。我编辑我的回复并给你一个小例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多