2012-09-08 38 views
0

我想發送文件從客戶端到服務器,並能在將來再次做到這一點。從客戶端發送文件到服務器,不要丟失連接,有可能嗎?

所以我的客戶端連接到服務器並上傳文件,確定 - 它的工作原理,但它在客戶端掛在年底..

所以這裏是我的代碼,在服務器端頗爲相似。在堆棧中發現

private void SenderFile(File file) { 


    try { 

      FileInputStream fis = new FileInputStream(file); 
      OutputStream os = socket.getOutputStream(); 

      IoUtil.copy(fis, os); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

IoUtils :)

public static class IoUtil { 

    private final static int bufferSize = 8192; 

    public static void copy(InputStream in, OutputStream out) 
      throws IOException { 
     byte[] buffer = new byte[bufferSize]; 
     int read; 

     while ((read = in.read(buffer, 0, bufferSize)) != -1) { 
      out.write(buffer, 0, read); 
     } 
     out.flush(); 
    } 
} 

解釋:我的客戶端已連接到服務器的套接字,我的任何文件發送給他。 我的服務器下載它,但最終掛起,因爲他正在聽更多的信息。 如果我選擇另一個文件,我的服務器將下載新的數據到現有的文件。

我怎樣才能上傳任何文件到服務器,使我的服務器工作,並能夠正確下載另一個文件?

ps。如果我在功能out.close的末尾添加了ioutil.copy,我的服務器將工作,但連接將會丟失。我不知道該怎麼做:{


更新後: 客戶端:

private void SenderFile(File file) { 
    try { 

     FileInputStream fis = new FileInputStream(file); 
     OutputStream os = socket.getOutputStream(); 

     DataOutputStream wrapper = new DataOutputStream(os); 
     wrapper.writeLong(file.length()); 
     IoUtil.copy(fis, wrapper); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

服務器端(線程監聽來自客戶端的任何消息):

public void run() { 
    String msg; 
    File newfile; 

    try { 
     //Nothing special code here 

     while ((msg = reader.readLine()) != null) { 


      String[] message = msg.split("\\|"); 
      if (message[0].equals("file")) {//file|filename|size 

       String filename = message[1]; 
       //int filesize = Integer.parseInt(message[2]); 

       newfile = new File("server" + filename); 


       InputStream is = socket.getInputStream(); 
       OutputStream os = new FileOutputStream(newfile); 

       DataInputStream wrapper = new DataInputStream(is); 

       long fileSize = wrapper.readLong(); 
       byte[] fileData = new byte[(int) fileSize]; 
       is.read(fileData, 0, (int) fileSize); 
       os.write(fileData, 0, (int) fileSize); 


       System.out.println("Downloaded file"); 
      } else 

       //Nothing special here too 
     } 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

} 

好,現在我可以下載文件 - 仍然有一次,另一個下載但無法閱讀。例如,第二次我想通過客戶端發送file.png。我在服務器上得到它,但是這個文件是不可能查看的。 在此先感謝:)

+0

使用IOUtil.closeQuitely()關閉流。 – Vikdor

回答

2

您需要讓您的服務器能夠區分文件。最簡單的方法是事先告訴接收端對單個文件需要多少個字節;這樣,它就知道何時停止閱讀並等待另一個閱讀。

這是SenderFile方法可能是什麼樣子:

private void SenderFile(File file) 
{ 
    try 
    { 
     FileInputStream fis = new FileInputStream(file); 
     OutputStream os = socket.getOutputStream(); 

     DataOutputStream wrapper = new DataOutputStream(os); 
     wrapper.writeLong(file.length()); 
     IoUtil.copy(fis, wrapper); 
    } 
    catch (Exception ex) 
    { 
     ex.printStackTrace(); 
    } 
} 

這是ReceiveFile方法可能是什麼樣子:

// the signature of the method is complete speculation, adapt it to your needs 
private void ReceiveFile(File file) 
{ 
    FileOutputStream fos = new File(file); 
    InputStream is = socket.getInputStream(); 
    DataInputStream wrapper = new DataInputStream(is); 

    // will not work for very big files, adapt to your needs too 
    long fileSize = wrapper.readLong(); 
    byte[] fileData = new byte[fileSize]; 
    is.read(fileData, 0, fileSize); 
    fos.write(fileData, 0, fileSize); 
} 

然後不關閉套接字。

+0

問題是,我可以下載另一個文件,但他是不可讀的。我會更新代碼 – deadfish

+0

你看到任何解決方案嗎? – deadfish

+0

@Lumma,你有沒有試過用一個簡單的文本文件來查看它是如何被破壞的? – zneak

相關問題