Search code examples
javaudpclient-servermp3

About uploading mp3 files from clients to the server using UDP


I am quite new to StackOverflow, if my question is inappropriately asked or confusing, please let me know, thank you!

I am working on an audio streaming project, in which the clients are allowed to upload their mp3 files to the server. The server will store them into a playlist and stream the songs back to all the clients. Here is my code for the client to upload the 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();
        }
    }

The Problem lies here:

serverSocket.send(sendingAirMail);

As it will give me this error:

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)

After looking up google, I learned that it is because the UDP has a limit of size in each package delivered, so I wish to know how to separate the UDP package properly in this case? I know the TCP will be better in this case, but I think I need to learn how to separate packages anyway because I need to stream back the byte arrays from the server using UDP. Any help will be appreciated!

I can post my server and other client information if needed.


Solution

  • The thing is that you need to cut your file into several pieces and deliver them. For UDP, you need some things to make sure the file is complete and correct. Here are some suggestions:

    First, you need to cut your file, so you need to give a seq flag in the head. What's more you may need some extra infomations like the whole size of file, the timestamp and so on.

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

    Then, it's better to build a send buffer and recive buffer, check every time if the buffer is empty, if not, send/receive it.

    After receiving some pieces, you need to rebuild them using the seq flag. When some seq gets lost, you need retransmission. So you need a retransmission design here.

    In a word, you need the following things at least:

    1. A user defined head before information
    2. cut/rebuild file
    3. retransmission(GBN or FEC or both)

    Hope that can help you.