关于使用UDP从客户端上传mp3文件到服务器
About uploading mp3 files from clients to the server using UDP
我是 Whosebug 的新手,如果我的问题被不恰当地提出或混淆,请告诉我,谢谢!
我正在做一个音频流项目,允许客户端将他们的 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.run(client.java:67)
查了下google,得知是因为UDP每次发送的包都有大小限制,所以想知道这种情况下UDP包如何正确分离?我知道在这种情况下 TCP 会更好,但我认为无论如何我都需要学习如何分离包,因为我需要使用 UDP 从服务器流回字节数组。任何帮助将不胜感激!
如果需要,我可以 post 我的服务器和其他客户端信息。
问题是您需要将您的文件分成几部分并提交。对于 UDP,您需要一些东西来确保文件的完整性和正确性。以下是一些建议:
首先,你需要切割你的文件,所以你需要在头部给出一个seq标志。此外,您可能需要一些额外的信息,例如文件的总大小、时间戳等。
struct msg {
int seq;
int total_seq;
int size;
void *data;
};
然后,最好建立一个发送缓冲区和接收缓冲区,每次检查缓冲区是否为空,如果没有,send/receive它。
收到一些片段后,您需要使用 seq 标志重建它们。当某些seq丢失时,您需要重传。所以这里需要一个重传设计。
总之,你至少需要具备以下条件:
- 一个用户定义的head前信息
- cut/rebuild 文件
- 重传(GBN 或 FEC 或两者)
希望对您有所帮助。
我是 Whosebug 的新手,如果我的问题被不恰当地提出或混淆,请告诉我,谢谢!
我正在做一个音频流项目,允许客户端将他们的 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.run(client.java:67)
查了下google,得知是因为UDP每次发送的包都有大小限制,所以想知道这种情况下UDP包如何正确分离?我知道在这种情况下 TCP 会更好,但我认为无论如何我都需要学习如何分离包,因为我需要使用 UDP 从服务器流回字节数组。任何帮助将不胜感激!
如果需要,我可以 post 我的服务器和其他客户端信息。
问题是您需要将您的文件分成几部分并提交。对于 UDP,您需要一些东西来确保文件的完整性和正确性。以下是一些建议:
首先,你需要切割你的文件,所以你需要在头部给出一个seq标志。此外,您可能需要一些额外的信息,例如文件的总大小、时间戳等。
struct msg {
int seq;
int total_seq;
int size;
void *data;
};
然后,最好建立一个发送缓冲区和接收缓冲区,每次检查缓冲区是否为空,如果没有,send/receive它。
收到一些片段后,您需要使用 seq 标志重建它们。当某些seq丢失时,您需要重传。所以这里需要一个重传设计。
总之,你至少需要具备以下条件:
- 一个用户定义的head前信息
- cut/rebuild 文件
- 重传(GBN 或 FEC 或两者)
希望对您有所帮助。