2012-12-12 136 views
2

我在做一个客户端服务器。我已经知道服务器可以发送硬编码文件,但不是指定的客户端。我将不得不发送文本文件。据我了解:客户端首先发送文件名,然后,服务器发送它,没有什么复杂的,但我得到各种错误,这段代码得到一个连接重置/套接字关闭错误。主要的问题是,没有太多时间研究网络。Java请求文件,发送文件(客户端服务器)

我很感激任何帮助,我可以得到。

编辑。 我发现了一个解决办法,关闭一个流导致套接字关闭,为什么?它不应该发生,应该吗?

服务器端:

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(); 
+0

您在阅读之前是否尝试过使用System.out.println(sdata.available())?也许没有什么可读的。 –

+0

该代码没有运行那么远检查:/ – MustSeeMelons

+0

但它是否到达位置= sdata.readUTF(),你说连接重置?我的意思是在那之前。 –

回答

1

尝试从服务器读取文件中的数据块,而写入客户端输出流,而不是创建一个临时的字节数组,读取整个文件到内存。如果请求的文件很大,怎么办?还要在finally块中关闭服务器端的新Socket,以便在引发异常时关闭套接字。

服务器端:

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行到一行。

org.apache.commons.io.IOUtils.copy(is, out); 

注意,具有使用绝对路径来提供文件服务到远程客户端的服务器是潜在的危险和目标文件应该被限制在一个给定的目录和/或设置文件类型。不想将系统级文件提供给未经身份验证的客户端。

相关问题