2012-12-12 43 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); 

注意,具有使用絕對路徑來提供文件服務到遠程客戶端的服務器是潛在的危險和目標文件應該被限制在一個給定的目錄和/或設置文件類型。不想將系統級文件提供給未經身份驗證的客戶端。

相關問題