Java-使用套接字通过浏览器下载文件
我当时正在学习JavaJava-使用套接字通过浏览器下载文件,java,sockets,http-headers,download,serversocket,Java,Sockets,Http Headers,Download,Serversocket,我当时正在学习JavaSocket,我试图开发一个Socket,使用端口80从浏览器下载一个文件 因此,我运行我的主类(下面的源代码),它将在我想要的任何端口中打开一个Socket。 然后外面的人将访问http://MY_IP:MY_PORT/download/FILE_NAME 我让这一切都正常工作,但是客户端的文件大小是0字节(对于小文件),对于更大的归档文件,文件大小稍微小一些(原始600mb,下载540mb+) 我真的检查了我的代码很多次,我没有发现任何错误,我也从Javalibs改为A
Socket
,我试图开发一个Socket
,使用端口80从浏览器下载一个文件
因此,我运行我的主类(下面的源代码),它将在我想要的任何端口中打开一个Socket
。
然后外面的人将访问http://MY_IP:MY_PORT/download/FILE_NAME
我让这一切都正常工作,但是客户端的文件大小是0字节(对于小文件),对于更大的归档文件,文件大小稍微小一些(原始600mb,下载540mb+)
我真的检查了我的代码很多次,我没有发现任何错误,我也从Javalibs改为ApacheCommons,认为这会有所帮助,但没有成功
所以,也许我认为我在响应标题上有什么错误
你们能帮帮我吗?
提前谢谢
类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();
}
}
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();
}
}
}
类HTTPDownloadThread
:
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();
}
}
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();
}
}
}
导入java.io.File;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.net.Socket;
导入java.net.SocketException;
导入java.nio.file.Files;
导入java.nio.file.path;
类HTTPDownloaderThread扩展线程{
私有静态最终整数缓冲区大小=4096;
专用插座;
专用字节[]buf=新字节[缓冲区大小];
私有输出流输出;
私有输入流是;
HTTPDownloaderThread(最终套接字){
this.socket=socket;
}
公开募捐{
int numberRead=0;
试一试{
out=socket.getOutputStream();
is=socket.getInputStream();
numberRead=is.read(buf,0,缓冲区大小);
System.out.println(“读取”+numberRead);
如果(numberRead出于一个原因,请在标题和数据之间添加另一个“\r\n”。检查HTTP响应;内容长度标题是否报告下载文件的正确文件大小?这些文件在客户端上的可用性是否与在服务器上的可用性相同?
Web代理始终有助于调试HTTP(或其他客户端服务器)应用程序:)
另外,我假设您在浏览器上指定端口11000,因为您在服务器上收听的是端口11000。该网站不允许我发表评论,但我认为我应该通过使用
Files.copy("path",outStreamObj);
outStreamObj.close();
socketObj.close();
将导致下载不完整或损坏,但如果仍要使用,则不得关闭outStreamObj和socketObj。使用上述代码(至少从我的观察来看)文件传输速度很快。如果尝试关闭,将报告管道断开或连接重置,或无法完成下载(冻结)
相反,使用以下代码可以将outStreamObj作为socketObj关闭,但是从socket下载文件的速度很慢,可能是因为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();
嗯,您是在尝试上载还是下载?您的HTTPDownloaderThread
似乎在尝试上载…虽然它也在尝试在发送请求之前从套接字读取数据,但这不会很好地工作…可能是@jonsket的重复,客户端正在下载,我之前只读取了他的头请求。@RemyLebeau,不是重复的d、 默认情况下,我正在尝试使用Java创建自己的服务器,不涉及其他LIB。此外,由于代码实际上不支持范围请求,所以请删除接受范围:字节头。并且添加连接:关闭头,因为服务器在发送文件后正在断开客户端连接。@Joy Rê,谢谢,添加ano标题和数据之间的“\r\n”使其按预期工作!其他一切正常。