关于使用UDP从客户端上传MP3文件到服务器的问题

问题描述 投票:0回答:1

我是StackOverflow的新手,如果我的问题问得不恰当或让人困惑,请告诉我,谢谢!我正在做一个音频流媒体项目,客户可以将MP3文件上传到服务器上。

我正在做一个音频流媒体项目,在这个项目中,客户可以上传他们的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从服务器流回字节数组。任何帮助将被感激!

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

java udp client-server mp3
1个回答
0
投票

事情是,你需要把你的文件切成几块,然后传递给他们。对于UDP,你需要一些东西来确保文件是完整和正确的。这里有一些建议。

首先,你需要把你的文件切开,所以你需要在文件头给一个seq标志。还有,你可能需要一些额外的信息,比如整个文件的大小,时间戳等等。

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

然后,最好建立一个发送缓冲区和接收缓冲区,每次检查缓冲区是否为空,如果不是,就发送接收。

在接收到一些片段后,你需要使用seq标志重建它们。当一些seq丢失时,你需要重传。所以你需要在这里进行重传设计。

一句话,你至少需要以下东西。

  1. 一个用户定义的信息前的头
  2. 剪切重建文件
  3. 转发(GBN或FEC或两者兼有)

希望能帮到你。

© www.soinside.com 2019 - 2024. All rights reserved.