简体   繁体   English

Java-使用套接字通过浏览器下载文件

[英]Java - Download a file through browser using a Socket

i was studying Java Socket and i tried to develop a Socket using port 80 to download a file from browser. 我正在学习Java Socket并尝试使用端口80开发Socket以从浏览器下载文件。

So, i run my main class (source below), it will open a Socket in any port i want to. 所以,我运行我的主类(下面的源代码),它将在我想要的任何端口中打开一个Socket Then someone outside will access http://MY_IP:MY_PORT/download/FILE_NAME 然后,外面的人将访问http://MY_IP:MY_PORT/download/FILE_NAME

I got this all working, however the filesize on client side is 0 bytes (for small files), and slightly lower size for bigger archives (original 600mb, download 540mb+-) 我都完成了所有工作,但是客户端的文件大小为0字节(对于小文件),对于较大的档案文件,其文件大小略低(原始600mb,下载540mb +-)

I really checked my code a lot of times, i couldn't find any error, i also changed from java libs to Apache-commons thinking it would help, but no success. 我确实检查了很多次代码,找不到任何错误,我也从Java库更改为Apache-commons,以为这会有所帮助,但没有成功。

so maybe i think i got something wrong on Response headers. 所以也许我认为我在Response标头上出了点问题。

Can you guys help me please? 你们能帮我吗? Thanks in advance. 提前致谢。

Class HTTPDownload : HTTPDownload

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

class HTTPDownloader {
    Socket incoming = null;
    ServerSocket server = null;

    public HTTPDownloader(){
        int port = 11000;

        try{
            server = new ServerSocket(port);
            System.out.println("Creating SocketServer on Port " + port);
        }catch(IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

        System.out.println("Preparing to accept connections...");
        while(true){
            try{
                incoming = server.accept();
                System.out.println("connection!");
                HTTPDownloaderThread thread1 = new HTTPDownloaderThread(incoming);
                thread1.start();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) throws IOException{
        new HTTPDownloader();
    }
}

Class HTTPDownloadThread : HTTPDownloadThread

 import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.nio.file.Files;
import java.nio.file.Paths;

class HTTPDownloaderThread extends Thread {
    private static final int BUFFER_SIZE = 4096;
    private Socket socket;
    private byte[] buf = new byte[BUFFER_SIZE];
    private OutputStream out;
    private InputStream is;

    HTTPDownloaderThread(final Socket socket){
        this.socket = socket;
    }

    public void run(){
        int numberRead = 0;

        try{
            out = socket.getOutputStream();      
            is = socket.getInputStream();
            numberRead = is.read(buf, 0, BUFFER_SIZE);
            System.out.println("read " + numberRead);

            if(numberRead<0)
                return;

            byte[] readBuf = new byte[numberRead];
            System.arraycopy(buf, 0, readBuf, 0, numberRead);

            String header = new String(readBuf);
            System.out.println(header);
            String fileName = header.split("\r\n")[0].split(" ")[1].substring(1);
            System.out.println(socket.getInetAddress().getHostAddress()+" asked for file: "+fileName);

            File f = new File("C:\\TestFolder\\"+fileName);

            out.write("HTTP/1.1 200 OK\r\n".getBytes());
            out.write("Accept-Ranges: bytes\r\n".getBytes());
            out.write(("Content-Length: "+f.length()+"\r\n").getBytes());
            out.write("Content-Type: application/octet-stream\r\n".getBytes());
            out.write(("Content-Disposition: attachment; filename=\""+fileName+"\"\r\n").getBytes());
            out.write("\r\n".getBytes()); // Added as Joy Rê proposed, make it work!
            Files.copy(Paths.get("C:\\TestFolder\\"+fileName) , out);
            System.out.println("File upload completed!");
//          out.flush();
            out.close();
            socket.close();
        }catch(SocketException e) {
            System.out.println(e.getMessage());
        }catch(Exception e){
            e.printStackTrace();
        }
    }

}

For one thing, add another "\\r\\n" between headers and data. 一方面,在标题和数据之间添加另一个“ \\ r \\ n”。 Check your HTTP Response; 检查您的HTTP响应; does the Content-Length header report the correct file size for the downloaded file? Content-Length标头是否报告下载文件的正确文件大小? Do the files show up usable on the client in the same way they were on the server? 文件显示在客户端上的方式与在服务器上显示的方式一样吗? Web proxies always helpful in debugging HTTP (or other client-server) applications :) Web代理始终有助于调试HTTP(或其他客户端-服务器)应用程序:)

Also, I'm assuming you are specifying port 11000 on the browser, as that's what you're listening on on the server 另外,我假设您在浏览器上指定端口11000,因为这是您在服务器上监听的端口

The website does not let me to comment but i thought that I should tell about my findings.. By using 该网站不允许我发表评论,但我认为我应该告诉我我的发现..通过使用

  Files.copy("path",outStreamObj);
  outStreamObj.close();
  socketObj.close();

Will cause incomplete or corrupt downloads but if still want to use then outStreamObj and socketObj must not be closed the files transfer is fast with the above code (atleast from my observation). 会导致下载不完整或损坏,但如果仍要使用,则必须关闭outStreamObj和socketObj,使用上面的代码可以快速进行文件传输(至少是我的观察)。 If you try to close it will report Broken Pipe or Connection reset or will not complete the download(freeze it). 如果您尝试关闭,它将报告管道破裂或连接重置,或者无法完成下载(冻结)。

Instead using the following code will let you close the outStreamObj as socketObj but file download is slow from the socket probably because of while loop. 而是使用以下代码来让您将outStreamObj作为socketObj关闭,但是从套接​​字下载文件很慢,可能是由于while循环所致。

 Socket socket=serverSocket.accept();
 FileInputStream fs=new FileInputStream(path);
 OutputStream out = socket.getOutputStream();
 //This is the change from the Files.copy()
 int reads=0;
 while((reads=fs.read())!=-1)
        {
            out.write(reads);
        }
        out.close();
        socket.close();

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

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