Java请求文件,发送文件(客户端-服务器) [英] Java request file, send file (Client-server)
问题描述
我正在制作一个客户端-服务器.我已经知道服务器可以发送硬编码文件,但不能发送指定的客户端.我将只需要发送文本文件.据我所知:客户端首先发送文件名,然后服务器发送它,没有什么复杂的,但是我遇到了各种各样的错误,这段代码出现了连接重置/套接字关闭错误.主要问题是,没有太多时间研究网络.
I'm making a Client-Server. I've gotten as far as that the server can send a hardcoded file, but not a client specified. I will have to send only text files. As far as I have understood: the clients firstly sends the file name and then, the server sends it, nothing complicated, but I'm getting all kinds of errors, this code is getting a connection reset/socket closed error. The main problem is, that hadn't got much time to research networking.
非常感谢我能得到的任何帮助.
Ill appreciate any help I can get.
编辑.我找到了一个解决方法,关闭流会导致套接字关闭,这是为什么?这不应该发生,是吗?
EDIT. I found a work around, closing a stream causes the socket to close, why is that? It shouldn't happen, should it?
服务器端:
InputStream sin=newCon.getInputStream();
DataInputStream sdata=new DataInputStream(sin);
location=sdata.readUTF();
//sdata.close();
//sin.close();
File toSend=new File(location);
byte[] array=new byte[(int)toSend.length()];
FileInputStream fromFile=new FileInputStream(toSend);
BufferedInputStream toBuffer=new BufferedInputStream(fromFile);
toBuffer.read(array,0,array.length);
OutputStream out=newCon.getOutputStream(); //Socket-closed...
out.write(array,0,array.length);
out.flush();
toBuffer.close();
newCon.close();
客户端:
int bytesRead;
server=new Socket(host,port);
OutputStream sout=server.getOutputStream();
DataOutputStream sdata=new DataOutputStream(sout);
sdata.writeUTF(interestFile);
//sdata.close();
//sout.close();
InputStream in=server.getInputStream(); //socket closed..
OutputStream out=new FileOutputStream("data.txt");
byte[] buffer=new byte[1024];
while((bytesRead=in.read(buffer))!=-1)
{
out.write(buffer,0,bytesRead);
}
out.close();
server.close();
推荐答案
尝试在写入客户端输出流的同时从服务器以块的形式读取文件,而不是创建临时字节数组并将整个文件读入内存.如果请求的文件很大怎么办?还要在 finally 块中关闭服务器端的新 Socket,这样即使抛出异常,socket 也会关闭.
Try reading the file in chunks from Server while writing to client output stream rather than creating a temp byte array and reading entire file into memory. What if requested file is large? Also close the new Socket on server-side in a finally block so socket is closed even if an exception is thrown.
服务器端:
Socket newCon = ss.accept();
FileInputStream is = null;
OutputStream out = null;
try {
InputStream sin = newCon.getInputStream();
DataInputStream sdata = new DataInputStream(sin);
String location = sdata.readUTF();
System.out.println("location=" + location);
File toSend = new File(location);
// TODO: validate file is safe to access here
if (!toSend.exists()) {
System.out.println("File does not exist");
return;
}
is = new FileInputStream(toSend);
out = newCon.getOutputStream();
int bytesRead;
byte[] buffer = new byte[4096];
while ((bytesRead = is.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.flush();
} finally {
if (out != null)
try {
out.close();
} catch(IOException e) {
}
if (is != null)
try {
is.close();
} catch(IOException e) {
}
newCon.close();
}
如果您使用 Apache Common IOUtils 库,那么您可以减少大部分代码以进行读/写文件到流.这里是 5 行到 1 行.
If you use Apache Common IOUtils library then you can reduce much of the code to read/write files to streams. Here 5-lines down to one line.
org.apache.commons.io.IOUtils.copy(is, out);
请注意,使用通过绝对路径向远程客户端提供文件的服务器具有潜在危险,目标文件应限制为给定目录和/或文件类型集.不想向未经身份验证的客户提供系统级文件.
Note that having a server that serves files by absolute path to remote clients is potentially dangerous and the target file should be restricted to a given directory and/or set of file types. Don't want to serve out system-level files to unauthenticated clients.
这篇关于Java请求文件,发送文件(客户端-服务器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!