Как сделать передачу файлов более эффективной Java
У меня есть два беспроводных компьютера, подключенных к беспроводному маршрутизатору N. Каждый из этих компьютеров подключен со скоростью 108-150 Мбит / с.
Теоретически, я должен быть в состоянии передавать со скоростью 13,5 МБ / с до 18,75 МБ / с, при абсолютных лучших условиях.
Первый компьютер (который отправляет) использует очень быстрый SSD, который составляет около 100 МБ / с, если я правильно помню. Загрузка процессора также остается ниже 20%.
Он отправил 1960273535 байт (1,8 ГБ) в 656367 мс. Это 2,8 МБ / с (22 из 108 мегабит). Когда я открываю диспетчер задач, я вижу, что используется только 25-27% сетевого подключения.
Я ищу любые идеи, предложения или улучшения, которые могут ускорить передачу (по сети). Я думал о буферизации файла с диска в потоке и отправке буферизованных данных из другого потока, но я не уверен, что это хорошая идея. Вот SSCCE:
Ведущий:
import java.io.*;
import java.net.*;
public class Host {
public static void main(String[] args) throws IOException {
ServerSocket servsock = new ServerSocket(15064);
Socket sock = servsock.accept();
long time = System.currentTimeMillis();
OutputStream out = sock.getOutputStream();
FileInputStream fileInputStream = new FileInputStream("C:\\complete.rar");
byte [] buffer = new byte[64*1024];
int bytesRead = 0;
long totalSent = 0;
while ( (bytesRead = fileInputStream.read(buffer)) != -1)
{
if (bytesRead > 0)
{
out.write(buffer, 0, bytesRead);
totalSent += bytesRead;
System.out.println("sent " + totalSent);
}
}
sock.close();
System.out.println("Sent " + totalSent + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}
Клиент:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
Socket sock = new Socket("127.0.0.1", 15064);
InputStream in = sock.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("output.rar");
byte [] buffer = new byte[64*1024];
int bytesRead = 0;
while ( (bytesRead = in.read(buffer)) != -1)
fileOutputStream.write(buffer, 0, bytesRead);
sock.close();
fileOutputStream.close();
}
}
Изменить: я попытался подключить сетевой диск и отправить файл через него, и Windows сделал еще хуже - 2,35 МБ / с. По этой статьеhttp://tinyurl.com/634qaqg подключение сетевого диска происходит быстрее, чем FTP, и у меня также нет времени, чтобы продолжать играть и настраивать FTP-сервер.
Edit2: после изменения таймера оказывается, что он передается со скоростью 3 МБ / с по WiFi. Я ненавижу "теоретическую" пропускную способность. Когда я покупаю что-то, я хочу знать, что это НАСТОЯЩАЯ производительность. Оказывается, код действительно ограничен скоростью WiFi. Я все еще открыт для предложений, хотя.
Редактировать 3: После запуска программы в локальной сети 100 Мбит / с ей удалось передать файл со скоростью 11,8 МБ / с. Это очень хорошо, учитывая, что максимальная скорость передачи составляет 12,5 МБ / с.