2012-04-24 3 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? В противном случае приемник перестает записывать байты в выходной файл (и, возможно, даже закрывает соединение?), В то время как отправитель все еще записывает данные в поток. –

+0

@AndreHolzner Да, я могу гарантировать, что это не проблема. – Stripies

ответ

0

Пожалуйста, прочтите этот answer, я не думаю, что еще можно сказать, кроме того, и я не вижу ничего в коде, который будет закрывать соединение.

От OTN Обсуждение

Описание WinSock: Ошибка может возникнуть, когда система локальной сети прерывает соединение. Это произойдет, если WinSock прервет установленное соединение после сбоя повторной передачи данных (приемник никогда не признает данные, отправленные на разъеме потока данных).

Сценарий TCP/IP: соединение будет тайм-аут, если локальная система не получает (ACK) теперь отправление данных. Он также будет тайм-аутом, если TCP-пакет (FIN) не является ACK'd (и даже если FIN является ACK'd, то в конечном итоге истечет, если FIN не возвращается).

Возможно, это связано с WindowsXP, и, похоже, оно также должно быть , возможно, связано с настройками брандмауэра Windows. В любом случае основной момент заключается в том, что прерывание возникло внутри локальной машины.

+0

Если это так, есть ли способ исправить это? – Stripies

0

Используйте BufferedInputStream для чтения 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

+0

Возможно, вам понадобится дополнительный BufferedOutputStream для метода чтения получателя. – eabraham

Смежные вопросы