2015-05-13 3 views
0

У меня проблема с отправкой файлов через сокет java. Иногда код работает, иногда нет. Я тестирую блок while в обоих, кажется, что код отправляет все байты, но сервер не получает (но даже в этом тесте файл отправляется правильно). В этом случае сервер прекратил принимать данные. Все файлы составляют около 150 КБ. Я использую порт 9191.Ошибка отправки файла через java-сокет

Сервер:

while (true) { 
     try { 
      Socket socket = ss.accept(); 
      ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 
      String fileName = in.readUTF(); 

      FileOutputStream fos = new FileOutputStream(destinationPath + fileName); 
      byte[] buf = new byte[1024]; 

      int len; 
      while ((len = in.read(buf)) >= 0) { 
       fos.write(buf, 0, len); 
      } 
      fos.flush(); 

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

Клиент:

try { 
     Socket socket = new Socket(host, port); 
     ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); 

     out.writeUTF(file.getName()); 
     out.writeLong(file.length()); 
     FileInputStream in = new FileInputStream(file); 
     byte[] buf = new byte[1024]; 

     int len; 
     while ((len = in.read(buf)) >= 0) { 
      out.write(buf, 0, len); 
     } 

     out.close(); 
     socket.close(); 

    } catch (Exception e) { 
     throw e; 
    } 

ответ

1

Сначала вы должны заменить ObjectInputStream и ObjectOutputStream с DataInputStream и DataOutputStream соответственно. Вы не сериализуете Java-объекты, и нет смысла использовать классы потоков, предназначенные для этой цели.

Во-вторых, вы отправляете длину файла в клиенте, но не специально читаете его на сервере. Вместо этого он добавляется в начало файла.

+1

Я сделал изменения и понять, что это отправить 1 файл, а второй (одинаковые или разные) файл кода на сервер переходит в бесконечный цикл в «в то время как ((Len = in.read (buf))> = 0) {", потому что я поставил println после блока, и он никогда не отображается во второй раз. – Marcelo

+0

@Marcelo, если вы хотите отправить несколько файлов с клиента на сервер, я бы предложил сначала отправить int, который сообщает серверу, сколько файлов ожидать. Затем для каждого файла начинайте с имени файла, затем его размера, затем по размеру байтов. На сервере, читаемом в имени файла, это размер, а затем размер байтов размера от потока к файлу и повторение до тех пор, пока из файлов не будет. –

+0

На самом деле, в localhost работает, но на сервере ubuntu удаленно нет. Я очищаю правила iptables и ничего. В этом случае я отправляю один файл, а через несколько секунд - другой файл. – Marcelo

1

На клиенте вы говорите,

out.writeUTF(file.getName()); 
out.writeLong(file.length()); 

Но на сервере вы говорите,

String fileName = in.readUTF(); 
FileOutputStream fos = new FileOutputStream(destinationPath + fileName); 
byte[] buf = new byte[1024]; 
int len; 
while ((len = in.read(buf)) >= 0) { 
    fos.write(buf, 0, len); 
} 
fos.flush(); 

Вы не читали длину файла. И вам нужно убедиться, что вы прочитали все отправленные байты (или ваш файл будет поврежден). Также не забудьте указать close()FileOutputStream (или используйте try-with-resources, чтобы закрыть его для вас). Нечто подобное,

String fileName = in.readUTF(); 
try (FileOutputStream fos = new FileOutputStream(destinationPath 
     + fileName)) { 
    long size = in.readLong(); 
    byte[] buf = new byte[1024]; 
    long total = 0; 
    int len; 
    while ((len = in.read(buf)) >= 0) { 
     fos.write(buf, 0, len); 
     total += len; 
    } 
    if (total != size) { 
     System.err.printf("Expected %d bytes, but received %d bytes%n", 
       size, total); 
    } 
} 
+0

Я сделал изменения и понял, что он отправляет 1 файл, а второй (тот же или другой) файл, код на сервере переходит в бесконечный цикл в «while ((len = in.read (buf))> = 0) {", потому что я поставил println после блока, и он никогда не отображается во второй раз. – Marcelo

+0

Убедитесь, что вы отправляете другой файл ... код выше отправляет 1 файл (не несколько файлов - и клиент отправил вызовы 'socket.close();') –

+0

Фактически, в localhost работает, но на сервере ubuntu дистанционно нет. Я очищаю правила iptables и ничего. В этом случае я отправляю один файл, а через несколько секунд - другой файл, снова вызывающий SocketClient. – Marcelo

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