Проблема передачи файлов в сети Java - PullRequest
3 голосов
/ 04 августа 2011

Я пишу небольшую Java-программу, которая может измерять скорость моей локальной сети. Это первый раз, когда я работаю с сокетами, но я собрал программу, которая работает. Единственная проблема заключается в том, что измерения далеко не точные (слишком низкие).

Это код сервера:

ServerSocket servsock = new ServerSocket(13267);
while (true) {
    System.out.println("Waiting...");

    Socket sock = servsock.accept();
    System.out.println("Accepted connection : " + sock);

    File myFile = new File("test.txt");
    FileInputStream in = new FileInputStream(myFile);
    OutputStream out = sock.getOutputStream();

    int bytes = 0;
    byte[] buffer = new byte[8192];
    int len;

    while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
        bytes += len;
    }

    System.out.println("Transfer completed, " + bytes + " bytes sent");

    out.flush();
    sock.close();
}

Это код клиента:

Socket sock = new Socket("192.168.0.100", 13267);
System.out.println("Connecting to : " + sock);

InputStream in = sock.getInputStream();
FileOutputStream out = new FileOutputStream("received.txt");

int bytes = 0;
byte[] buffer = new byte[8192];
int len;

long start = System.currentTimeMillis();

while ((len = in.read(buffer)) > 0) {
    out.write(buffer, 0, len);
    bytes += len;
}

long end = System.currentTimeMillis();

out.close();
sock.close();

double kbps = (bytes / 1000) / ((end - start) / 1000);
System.out.println("Speed: " + kbps + " kbps");

Это потому, что я работаю со своими собственными буферами, которые замедляют все или в чем может быть проблема? Также приветствуются советы и подсказки.

Ответы [ 3 ]

4 голосов
/ 04 августа 2011

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

Я предлагаю отправлять данные в течение не менее 2-10 секунд.

В этой статье приведен пример кода о самом быстром способе передачи данных через сокет. Насколько быстры Java-сокеты


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

double kbps = (bytes / 1000) / ((end - start) / 1000);

Скажем bytes равно 2100 иend - start равно 1900, вы получите

double kbps = (2100 / 1000) / (1900 / 1000);
double kbps = 2 / 1; == 2.

почти то же самое, что и (но с меньшей ошибкой)

double kbps = bytes / (end - start);

лучше

double kbps = (double) bytes / (end - start);

Для отправки пустых данных

byte[] bytes = new byte[8*1024];
OutputStream out = socket.getOutputStream();
// send data for given amount of time, e.g. 2000 ms
long endTime = System.currentTimeMS() + timeToSendDataMS;
do {
    out.write(bytes);
} while(endTime > System.currentTimeMS());

Для чтения пустых данных

long total = 0;
byte[] bytes = new byte[8*1024];
InputStream in = socket.getInputStream();
int len;
while((len = in.read(bytes)) != -1)
    total += len;
0 голосов
/ 05 августа 2011

Ваш код неверен.Вы заканчиваете таймер в неправильной точке.Передача не завершена, пока вы не очистите или не закроете выходной поток.

0 голосов
/ 04 августа 2011

Это потому, что вы записываете на диск каждый пакет 8K, который вы получаете на стороне клиента .

FileOutputStream out = new FileOutputStream("received.txt");
...
while ((len = in.read(buffer)) > 0) {
    out.write(buffer, 0, len);
    ...
}

Это не обязательно для теста скоростиДостаточно просто прочитать байты в буфер.Пропустите запись пакетов в файл в коде клиента.При желании вы можете записать полученные пакеты в ByteArrayOutputStream.Java сама будет обрабатывать выделение в пространстве кучи JVM.И это не повлияет на тест скорости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...