Java请求文件、发送文件(客户端服务器)
我正在做一个客户端服务器。我已经了解到服务器可以发送硬编码文件,但不能发送指定的客户端。我只能发送文本文件。据我所知:客户端首先发送文件名,然后服务器发送,这并不复杂,但我得到了各种各样的错误,这段代码得到了连接重置/套接字关闭错误。主要问题是,他们没有太多时间研究网络 我很感激能得到的任何帮助 编辑。 我找到了一个解决方案,关闭一个流会导致套接字关闭,这是为什么?这不应该发生,是吗 服务器端:Java请求文件、发送文件(客户端服务器),java,sockets,networking,connection-reset,Java,Sockets,Networking,Connection Reset,我正在做一个客户端服务器。我已经了解到服务器可以发送硬编码文件,但不能发送指定的客户端。我只能发送文本文件。据我所知:客户端首先发送文件名,然后服务器发送,这并不复杂,但我得到了各种各样的错误,这段代码得到了连接重置/套接字关闭错误。主要问题是,他们没有太多时间研究网络 我很感激能得到的任何帮助 编辑。 我找到了一个解决方案,关闭一个流会导致套接字关闭,这是为什么?这不应该发生,是吗 服务器端: InputStream sin=newCon.getInputStream(); D
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();
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();
}
客户端:
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块中关闭服务器端的新套接字,这样即使抛出异常,套接字也会关闭 服务器端:
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();
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();
}
如果使用库,则可以减少将文件读/写到流的大量代码。这里5行到1行
org.apache.commons.io.IOUtils.copy(is, out);
请注意,如果服务器以绝对路径向远程客户端提供文件,则可能存在危险,目标文件应限制为给定目录和/或一组文件类型。不希望向未经身份验证的客户端提供系统级文件。在读取之前,您是否尝试过system.out.println(sdata.available())呢?可能还没有什么要读的。代码没有运行到那么远的地方进行检查:/但是它是否到达location=sdata.readUTF(),在那里您说连接已重置?我的意思是在此之前。抱歉,但它没有被重置,我已经解决了,在这些代码片段中,当尝试从套接字获取输入/输出流时,套接字是关闭的。建议在将目标文件写入流之后在客户端调用sdata.flush()。为了在服务器端进行调试,您应该输出接收到的位置。