简体   繁体   English

通过 URLConnection 将音频文件从客户端传输到 Http 服务器

[英]Transfer Audio-File from Client to Http Server via URLConnection

i am currently working on a programming-project in my school.我目前正在我的学校从事一个编程项目。 I need to send an audio file (MIDI format) from the Client successfully to a Http Server.我需要将音频文件(MIDI 格式)从客户端成功发送到 Http 服务器。 I already tried to do this myself and did much research on the internet and in the Stackoverflow forum.我已经尝试自己做这件事,并在互联网和 Stackoverflow 论坛上做了很多研究。 Currently it is possible to send the file from the client to the server, but on the server side, the audio file is not playable.目前可以将文件从客户端发送到服务器,但在服务器端,音频文件无法播放。

The following is the client-side-code:以下是客户端代码:

private static void sendPOST() throws IOException{
    final int mid = 1;
    final String POST_URL = "http://localhost:8080/musiker/hörprobe?mid="+mid;
    final File uploadFile = new File("C://Users//Felix Ulbrich//Desktop//EIS Prototype MIDIs//Pop//BabyOneMoreTime.mid");
    String boundary = Long.toHexString(System.currentTimeMillis()); 
    String CRLF = "\r\n";
    String charset = "UTF-8";
    URLConnection connection = new URL(POST_URL).openConnection();
    connection.setDoOutput(true);
    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    try (
            OutputStream output = connection.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
        ){
        writer.append("--" + boundary).append(CRLF);
        writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + uploadFile.getName() + "\"").append(CRLF);
        writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(uploadFile.getName())).append(CRLF);
        writer.append("Content-Transfer-Encoding: binary").append(CRLF);
        writer.append(CRLF).flush();
        Files.copy(uploadFile.toPath(), output);
        output.flush();
        writer.append(CRLF).flush();

        writer.append("--" + boundary + "--").append(CRLF).flush();

        int responseCode = ((HttpURLConnection) connection).getResponseCode();
        System.out.println(responseCode);
        }
}

The following is the server-side-code:以下是服务器端代码:

int FILE_SIZE = Integer.MAX_VALUE-2;
                    int bytesRead = 0;
                    int current = 0;
                    FileOutputStream fos = null;
                    BufferedOutputStream bos = null;
                    byte[] mybytearray = new byte[FILE_SIZE];
                    String FILE_TO_RECEIVED = "C://root//m"+musikerid+"hp"+(hörprobenzaehler+1)+".mid";
                    File f = new File(FILE_TO_RECEIVED);
                    if(!f.exists()){
                        f.createNewFile();
                    }
                    InputStream input = t.getRequestBody();
                    fos = new FileOutputStream(FILE_TO_RECEIVED);
                    bos = new BufferedOutputStream(fos);
                    bytesRead = input.read(mybytearray,0,mybytearray.length);
                    current = bytesRead;
                    do{
                        bytesRead = input.read(mybytearray, current, mybytearray.length-current);
                        if(bytesRead >= 0){
                            current += bytesRead;
                        }
                    }while(bytesRead>-1);

                    bos.write(mybytearray,0,current);
                    bos.flush();
                    fos.close();
                    bos.close();
                    t.sendResponseHeaders(200, 0);
                    input.close();

I am pretty desperate right now, because i couldn't find any solution to this problem.我现在非常绝望,因为我找不到任何解决此问题的方法。 I need to use an HTTP server, but i don't need to use the TCP protocol (which is used right now via streams).我需要使用 HTTP 服务器,但我不需要使用 TCP 协议(​​现在通过流使用)。 I thought about a solution via ftp so i don't need to convert the file to a byte-array first.我想了一个通过 ftp 的解决方案,所以我不需要先将文件转换为字节数组。 I assume that the problem lies exactly there.我认为问题就出在那里。 The server can't create the audio-file (midi-file) correctly from the byte-array.服务器无法从字节数组正确创建音频文件(midi 文件)。 If anyone of you knows of a solution.如果你们中有人知道解决方案。 Pls, i need your help :D请,我需要你的帮助:D

Greetings, Gizpo问候, Gizpo

So I've dug deeper into the matter.所以我对这个问题进行了更深入的研究。 I've found several problems:我发现了几个问题:

  • You're mixing binary and character based I/O.您正在混合基于二进制和字符的 I/O。 While you get away with it on the client side, the server has a hard time dealing with this.当您在客户端摆脱它时,服务器很难处理这个问题。
  • You forgot to specify the size of the file you're sending over to the server.您忘记指定要发送到服务器的文件的大小。 On the server side you have no way of knowing (unless some one tells you beforehand) what the size (of the incoming file) will be.在服务器端,您无法知道(除非有人事先告诉您)(传入文件的)大小是多少。

I've edited your code and came up with this:我已经编辑了你的代码并想出了这个:


Client:客户:

private static void sendPOST() throws IOException{
        final int mid = 1;
        final String POST_URL = "http://localhost:8080/musiker/hörprobe?mid="+mid;
        final File uploadFile = new File("C://Users//Felix Ulbrich//Desktop//EIS Prototype MIDIs//Pop//BabyOneMoreTime.mid");

        String boundary = Long.toHexString(System.currentTimeMillis()); 
        String CRLF = "\r\n";
        String charset = "UTF-8";
        URLConnection connection = new URL(POST_URL).openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        
        try (
            OutputStream output = connection.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
        ) {
            writer.append("--" + boundary).append(CRLF);
            writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + uploadFile.getName() + "\"").append(CRLF);
            writer.append("Content-Length: " + uploadFile.length()).append(CRLF);
            writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(uploadFile.getName())).append(CRLF);
            writer.append("Content-Transfer-Encoding: binary").append(CRLF);
            writer.append(CRLF).flush();
            Files.copy(uploadFile.toPath(), output);
            output.flush();

            int responseCode = ((HttpURLConnection) connection).getResponseCode();
            System.out.println("Response code: [" + responseCode + "]");
        }
    }

Server:服务器:

@Override
public void handle(HttpExchange t) throws IOException {
    String CRLF = "\r\n";
    int fileSize = 0;
    
    String FILE_TO_RECEIVED = "C://root//m"+musikerid+"hp"+(hörprobenzaehler+1)+".mid";
    File f = new File(FILE_TO_RECEIVED);
    if (!f.exists()) {
        f.createNewFile();
    }
    
    InputStream input = t.getRequestBody();
    String nextLine = "";
    do {
        nextLine = readLine(input, CRLF);
        if (nextLine.startsWith("Content-Length:")) {
            fileSize = 
                Integer.parseInt(
                    nextLine.replaceAll(" ", "").substring(
                        "Content-Length:".length()
                    )
                );
        }
        System.out.println(nextLine);
    } while (!nextLine.equals(""));
    
    byte[] midFileByteArray = new byte[fileSize];
    int readOffset = 0;
    while (readOffset < fileSize) {
        int bytesRead = input.read(midFileByteArray, readOffset, fileSize);
        readOffset += bytesRead;
    }
    
    BufferedOutputStream bos = 
        new BufferedOutputStream(new FileOutputStream(FILE_TO_RECEIVED));
    
    bos.write(midFileByteArray, 0, fileSize);
    bos.flush();
    
    t.sendResponseHeaders(200, 0);
}

private static String readLine(InputStream is, String lineSeparator) 
    throws IOException {

    int off = 0, i = 0;
    byte[] separator = lineSeparator.getBytes("UTF-8");
    byte[] lineBytes = new byte[1024];
    
    while (is.available() > 0) {
        int nextByte = is.read();
        if (nextByte < -1) {
            throw new IOException(
                "Reached end of stream while reading the current line!");
        }
        
        lineBytes[i] = (byte) nextByte;
        if (lineBytes[i++] == separator[off++]) {
            if (off == separator.length) {
                return new String(
                    lineBytes, 0, i-separator.length, "UTF-8");
            }
        }
        else {
            off = 0;
        }
        
        if (i == lineBytes.length) {
            throw new IOException("Maximum line length exceeded: " + i);
        }
    }
    
    throw new IOException(
        "Reached end of stream while reading the current line!");       
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM