[英]Java Server using SOCKET to download a file upload to it via a browser on the same machine1
[英]Java - Download a file through browser using a Socket
我正在學習Java Socket
並嘗試使用端口80開發Socket
以從瀏覽器下載文件。
所以,我運行我的主類(下面的源代碼),它將在我想要的任何端口中打開一個Socket
。 然后,外面的人將訪問http://MY_IP:MY_PORT/download/FILE_NAME
我都完成了所有工作,但是客戶端的文件大小為0字節(對於小文件),對於較大的檔案文件,其文件大小略低(原始600mb,下載540mb +-)
我確實檢查了很多次代碼,找不到任何錯誤,我也從Java庫更改為Apache-commons,以為這會有所幫助,但沒有成功。
所以也許我認為我在Response標頭上出了點問題。
你們能幫我嗎? 提前致謝。
類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();
}
}
類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();
}
}
}
一方面,在標題和數據之間添加另一個“ \\ r \\ n”。 檢查您的HTTP響應; Content-Length標頭是否報告下載文件的正確文件大小? 文件顯示在客戶端上的方式與在服務器上顯示的方式一樣嗎? Web代理始終有助於調試HTTP(或其他客戶端-服務器)應用程序:)
另外,我假設您在瀏覽器上指定端口11000,因為這是您在服務器上監聽的端口
該網站不允許我發表評論,但我認為我應該告訴我我的發現..通過使用
Files.copy("path",outStreamObj);
outStreamObj.close();
socketObj.close();
會導致下載不完整或損壞,但如果仍要使用,則必須關閉outStreamObj和socketObj,使用上面的代碼可以快速進行文件傳輸(至少是我的觀察)。 如果您嘗試關閉,它將報告管道破裂或連接重置,或者無法完成下載(凍結)。
而是使用以下代碼來讓您將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.