Измерение фактических байтов, записанных через сокеты Java - PullRequest
3 голосов
/ 28 октября 2011

Я написал небольшую программу, которая отправляет / получает файлы от одного клиента другому.Я настроил индикаторы выполнения как для получателя, так и для клиента, но проблема в том, что отправитель, кажется, заканчивает свой индикатор выполнения намного быстрее, чем фактическая передача.Проблема заключается в том, как он вычисляет, сколько байтов было записано.Я предполагаю, что он считает, сколько байтов я прочитал в буфер, а не байтов, которые были отправлены через сеть, так как я могу найти решение этой проблемы?Получатель вычисляет полученные байты с правильной скоростью, но отправитель не выполняет свою часть правильно.

Установка более низкого размера буфера смещает разницу немного, но это все еще не правильно.Я попытался обернуть outputtream в CountingOutputStream, но он возвращает тот же результат, что и фрагмент кода ниже.В конечном итоге передача завершается правильно, но мне нужны правильные «отправленные» значения для обновления моего индикатора выполнения, как в том, что было фактически получено и записано на диск на стороне получателя.Я включил очень урезанный фрагмент кода, который представляет мой способ вычисления переданных байтов.Любые примеры решения будут очень полезны.

try
    {
    int sent = 0;
    Socket sk = new Socket(ip, port);
    OutputStream output = sk.getOutputStream();
    FileInputStream file = new FileInputStream(filepath);

    byte[] buffer = new byte[8092];

    while ((bytesRead = file.read(buffer)) > 0)
        {
        output.write(buffer, 0, bytesRead);
        sent += bytesRead;
        System.out.println(sent); // Shows incorrect values for the actual speed.
        }
    }

Ответы [ 2 ]

4 голосов
/ 28 октября 2011

Короче говоря, я не думаю, что вы можете получить точную видимость, которую вы ищете, исключительно со стороны отправителя, учитывая количество буферов между вами и самим проводом. Но я также не думаю, что это имеет значение. И вот почему:

  1. Байты считаются «отправленными», когда они передаются в сетевой стек. Когда вы отправляете небольшое количество байтов (например, ваш пример 8K), эти байты будут буферизироваться, и вызовы write () будут быстро возвращаться.

  2. Как только вы достигнете насыщения сети, ваши вызовы write () начнут блокироваться, когда различные сетевые буферы заполнятся - и, таким образом, вы получите реальное представление о времени.

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

2 голосов
/ 28 октября 2011

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

Ваша переменная sent - это точно.Вам нужна переменная received или processed, и для этого вам понадобится двусторонняя связь.

...