2012-04-24 100 views
1

這是我現在所擁有的。通過流發送文件

接收機:

public static void read(Socket socket, ObjectInputStream in) { 
    try { 
     String separator = in.readUTF(); 
     while (in.readByte() == -3) { 
      String path = in.readUTF().replaceAll(separator, System.getProperty("file.separator")); 
      File file = new File(new File(path).getParent()); 
      if (!file.exists()) { 
       file.mkdirs(); 
      } 
      FileOutputStream fos = new FileOutputStream(path); 
      int b = 0; 
      while ((b = in.readByte()) != -4) { 
       fos.write(b); 
      } 
      fos.close(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

發件人:

public static void send(String[] path) { 
    Socket socket; 
    try { 
     socket = new Socket(ip, port); 
     socket.setKeepAlive(true); 
    } catch (UnknownHostException e) { 
     return; 
    } catch (IOException e) { 
     return; 
    } 
    try { 
     ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 
     out.writeUTF(Devbox.getSeparator()); 
     for (String s : path) { 
      send(s, out); 
      out.writeByte(-2); 
     } 
     out.close(); 
     socket.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private static void send(String path, ObjectOutputStream out) { 
    File file = new File(path); 
    if (file.isDirectory()) { 
     File[] files = file.listFiles(); 
     for (File f : files) { 
      send(path + f.getName(), out); 
     } 
    } else { 
     try { 
      out.writeByte(-3); 
      out.writeUTF(path); 
      FileInputStream fis = new FileInputStream(file); 
      int b = 0; 
      while ((b = fis.read()) != -1) { 
       out.writeByte(b); 
      } 
      fis.close(); 
      out.writeByte(-4); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

這是我在發送方得到的錯誤。

java.net.SocketException: Software caused connection abort: socket write error 
    at java.net.SocketOutputStream.socketWrite0(Native Method) 
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) 
    at java.net.SocketOutputStream.write(SocketOutputStream.java:153) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.writeBlockHeader(ObjectOutputStream.java:1874) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1855) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.writeByte(ObjectOutputStream.java:1895) 
    at java.io.ObjectOutputStream.writeByte(ObjectOutputStream.java:760) 

它指向

   out.writeByte(b); 

它成功地將約25文件,則引發此錯誤。它每次都拋出它的文件不同,但它在大約5個文件的相同範圍內。接收器在發送者停止之前通常是一對特定文件之後停止。它停止,因爲in.readByte()== -3爲false。當它發生時,我得到了像-85和16這樣的數字。我在另一臺計算機上試了一下,因爲它說了一些關於軟件的內容,而且它完全一樣。有誰知道爲什麼會發生這種情況?我花了一天的時間試圖弄明白,並沒有得到任何答案。任何幫助是極大的讚賞。

+0

你能保證你的輸入文件不包含值-4嗎?否則,接收方停止將字節寫入輸出文件(甚至可能關閉連接?),而發送方仍在向流寫入數據。 – 2012-04-24 16:00:03

+0

@AndreHolzner是的,我可以保證這不是問題。 – Stripies 2012-04-24 16:10:26

回答

0

請仔細閱讀本answer,我不認爲任何人可以超出說,我還沒有看到你的代碼的任何將關閉連接。

從OTN討論

的WinSock描述:當本地網絡系統 中止的連接可能會出現錯誤。如果WinSock在數據重新傳輸失敗(接收方永不從 確認數據流套接字上發送的數據)後中止連接建立的 連接,則會發生這種情況。

TCP/IP場景:如果本地系統沒有收到發送數據的(ACK)請求,連接將超時。如果一個TCP數據包沒有被確認(即使FIN被ACK確認,如果沒有返回FIN,它最終會超時),它也會超時。

它似乎發生在WindowsXP更多,它似乎也可能是 可能與Windows防火牆設置有關。在任何情況下,突出的 點是中止已經發生在本地機器內部。

+0

如果是這樣的話,有什麼方法可以解決它嗎? – Stripies 2012-04-24 16:01:53

0

使用BufferedInputStream讀取send方法中的FileInputStream。

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 
while ((b = bis.read()) != -1) { 
    out.writeByte(b); 
} 

也可以嘗試互補的BufferedOutputStream

BufferedInputStream bos = new FileOutputStream(path); 
int b = 0; 
while ((b = in.readByte()) != -4) { 
    bos.write(b); 
} 

另外,你需要在文件傳輸完成後沖洗掉你的連接。

out.flush; 
+0

它做同樣的事情,它沒有幫助。 – Stripies 2012-04-24 15:57:18

+0

您可能需要在接收方的讀取方法上補充BufferedOutputStream。 – eabraham 2012-04-24 16:08:07