[JAVA] передача нескольких файлов через сокет.

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

[JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-13 20:05:45

всем привет!

пишу клиент-серверное приложение (бекаппер - файлы клиента копируются на сервер)
имеется сервер, который слушает порт и при входящем соединении создает клиентский тред для передачи файлов

Код: Выделить всё

(new Thread(new ClientHandler(serverSocket.accept())).start();

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

если нужен код - могу приаттачить.
спасибо!

Аватара пользователя
Electronik
капитан
Сообщения: 1579
Зарегистрирован: 2008-11-15 17:32:56
Откуда: Минск
Контактная информация:

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение Electronik » 2011-10-13 22:33:21

а зачем? проще создать список файлов и их контрольные суммы, например md5, и при приёме/передаче их сверять.
Начали Вы передавать несколько файлов, на середине второго соединение оборвалось, что делать будете?
Предскажем будущее hw по логам и дампу, снимем сглаз и порчу с рута, поможем придумать пароль(С)
Блог

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-13 23:19:38

Electronik писал(а):а зачем? проще создать список файлов и их контрольные суммы, например md5, и при приёме/передаче их сверять.
Начали Вы передавать несколько файлов, на середине второго соединение оборвалось, что делать будете?

алгоритм такой:
1. клиент передает список файлов для бекапа, дату их последней модификации (и еще можно передать массив размеров файлов или как Вы предложили значений md5)
2. сервер находит базовую директорию этого клиента и сравнивает по переданным именам файлов даты модификации, если файла нет либо дата модификации меньше той что у бекапируемого файла, то этот файл помещается в список на бекап
3. далее список передается обратно клиенту и тот начинает трансфер только нужных файлов.

т.о. если часть файлов уже передана, то она не будет передаваться в следующий раз.

а про md5 интересно, могли бы по подробнее? в том смысле что не понятно как их сравнивать при передаче, да и вся проблема не в сравнении того что получилось а в реализации копирования множества файлов в одно соединение.

спасибо!

Аватара пользователя
Electronik
капитан
Сообщения: 1579
Зарегистрирован: 2008-11-15 17:32:56
Откуда: Минск
Контактная информация:

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение Electronik » 2011-10-13 23:29:27

я имел ввиду то что если у Вас передалась только часть файла на сервер и произошел disconect. Что Вы будете делать в этом случае?
Предскажем будущее hw по логам и дампу, снимем сглаз и порчу с рута, поможем придумать пароль(С)
Блог

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-13 23:32:26

таки покажу код на всякий случай..
это клиент (в цикле создаю сокет и далее передаю этой функции на каждый файл):

Код: Выделить всё

public static void transmit(Socket socket, File file) {
      try {
         OutputStream os = socket.getOutputStream();
         InputStream is = new FileInputStream(file);
         byte[] buffer = new byte[size];
         
         for ( int count = -1; ( count = is.read(buffer) ) != -1; ) {
            os.write(buffer, 0, count);
         }
         is.close();
         os.flush();
         os.close();
      } catch ( IOException e ) {
         System.out.println("SocketTools.transmit(): IO error.");
         e.printStackTrace(System.out);
      }
   }

а эта на сервере (так же в цикле после socketServer.acept()):

Код: Выделить всё

public static void receive(Socket socket, File file) {
      try {
         InputStream is = socket.getInputStream();
         OutputStream os = new FileOutputStream(file);
         byte[] buffer = new byte[size];
         
         for ( int count = is.read(buffer); count != -1; count = is.read(buffer) ) {
            os.write(buffer, 0, count);
         }
         os.flush();
         os.close();
         is.close();
      } catch ( IOException e ) {
         System.out.println("SocketTools.receive(): IO error.");
         e.printStackTrace(System.out);
      }
   }

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-13 23:34:00

Electronik писал(а):я имел ввиду то что если у Вас передалась только часть файла на сервер и произошел disconect. Что Вы будете делать в этом случае?
хм, надо подумать, хотя это сейчас меня заботит меньше всего.. хотя парочку раз я натыкался на такое, но тогда при сбоях размер результирующего файла был равен 0. думаю это можно будет переиграть, но вот как реализовать сабж - я по прежнему хз.

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-14 3:01:21

так-с, сабж уже не актуален - разобрался.

касательно контрольной суммы, завтра буду имитировать дисконнект и смотреть что получится, так что спасибо за идею, Electronik

зы, для приличия - выкладываю упрощенное решение:

1. Server.java - сервер (получатель):

Код: Выделить всё

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
   private static final int port = 11111;
   private static ServerSocket ss;
   private Socket socket;
   
   public Server() {
      init();
   }
   
   private void init() {
      String[] files = new String[] { "destenation/30.mp4", "destenation/file1.pdf", "destenation/Swing.djvu" };
      long[] lens = new long[] { 349301530L, 4095L, 32252057L };
      
      if ( files == null || lens == null || files.length != lens.length ) {
         System.exit(1);
      }
      
      try {
         ss = new ServerSocket(port);
         for ( ; ; ) {
            socket = ss.accept();
            for ( int i = 0; i < files.length; i++ ) {
               SocketUtil.receive(socket, new File(files[i]), lens[i]);
            }
            if ( socket.isConnected() ) {
               socket.close();
            }
         }
      } catch ( IOException e ) {
         e.printStackTrace(System.out);
      }
   }
   
   public static void main(String[] args) {
      new Server();
   }
}

2. Client.java - клиент (отправитель):

Код: Выделить всё

import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client implements Runnable {
   private static final String host = "localhost";
   private static final int port = 11111;
   private Socket socket;
   
   public Client() {}
   
   @Override
   public void run() {
      init();
   }
   
   private void init() {
      String[] files = new String[] { "source/30.mp4", "source/file1.pdf", "source/Swing.djvu" };
      
      try {
         socket = new Socket(host, port);
         for ( int i = 0; i < files.length; i++ ) {
            SocketUtil.transmit(socket, new File(files[i]));
         }
      } catch ( UnknownHostException e ) {
         e.printStackTrace(System.out);
      } catch ( IOException e ) {
         e.printStackTrace(System.out);
      }
   }
   
   public static void main(String[] args) {
      new Thread(new Client()).start();
   }
}

3. SocketUtil.java - класс, содержащий необходимые функции для передачи (transfer) и получения (receive):

Код: Выделить всё

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class SocketUtil {
   private static final int size = 64 * 1024; // 64 KB
   
   private SocketUtil() {}
   
   public static void transmit(Socket socket, File file) {
      try {
         OutputStream os = socket.getOutputStream();
         InputStream is = new FileInputStream(file);
         byte[] buffer = new byte[size];
         
         for ( int count = -1; ( count = is.read(buffer) ) != -1; ) {
            os.write(buffer, 0, count);
         }
         os.flush();
         is.close();
      } catch ( IOException e ) {
         System.out.println("SocketUtil.transmits(): IO error.");
         e.printStackTrace(System.out);
      }
   }
   
   public static void receive(Socket socket, File file, long len) {
      try {
         InputStream is = socket.getInputStream();
         OutputStream os = new FileOutputStream(file);
         byte[] buffer = new byte[size];
         
         for ( int count = is.read(buffer), total = count; count != -1; count = is.read(buffer), total += count ) {
            os.write(buffer, 0, count);
            if ( total == len ) {
               break;
            }
         }
         os.flush();
         os.close();
      } catch ( IOException e ) {
         System.out.println("SocketUtil.receive(): IO error.");
         e.printStackTrace(System.out);
      }
   }
}


всем спасибо.

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-14 23:47:07

короч решение оказалось не работающим при копировании больших файлов (или при большом общем размере всех файлов)
так что to be continued... =(

Аватара пользователя
Fastman
ст. лейтенант
Сообщения: 1236
Зарегистрирован: 2006-07-07 10:20:38
Откуда: Минск. РБ

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение Fastman » 2011-10-15 15:52:18

Это неверное решение.
Зачем вы пишете велосипеды ? Для передачи файлов уже существует FTP/SFTP/etc
Или это чисто академическая разработка ?
Главное в жизни здоровье и любовь, остальное я все куплю.

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-15 21:22:05

Fastman писал(а):Это неверное решение.
Зачем вы пишете велосипеды ? Для передачи файлов уже существует FTP/SFTP/etc
Или это чисто академическая разработка ?

я пишу бекаппер а не фтп.
ps - иногда, для того чтобы научиться, надо написать свой велосипед.

daggerok
мл. сержант
Сообщения: 109
Зарегистрирован: 2009-03-06 14:54:05

Re: [JAVA] передача нескольких файлов через сокет.

Непрочитанное сообщение daggerok » 2011-10-16 2:35:08

тема не актуальна - разобрался.
помогли на javatalks.ru: _http://www.javatalks.ru/sutra133037.php#133037


Вернуться в «C/C++»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей