2012-04-24 99 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