[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();
я умею передавать файл через сокет, но при условии что после передачи байтов файла, сокет надо закрыть. и если имеются еще файлы, то для передачи каждого из них нужно снова создать соединение с сервером и т.д...
подскажите, как можно организовать передачу сразу нескольких файлов, имея инфо о них (имена файлов и их размер).

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

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2520 рублей (8 CPU, 8Gb RAM, 2x500Gb HDD, RAID 3ware 9750):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Electronik
капитан
Сообщения: 1585
Зарегистрирован: 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
капитан
Сообщения: 1585
Зарегистрирован: 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