На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

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

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Определение скорости существующего TCP соединения
    Приветствую всех зашедших!

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

    Есть приложение, состоящее из клиента и сервера (написаны на дельфи 2010, должны работать от XP и выше), которые устанавливают между собой TCP соединение используя с обоих сторон iocp (по мотиву этой статьи http://habrahabr.ru/post/145140/)

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

    На GetIfTable просьба не указывать, так как там видна скорость всего интерфейса.

    У Александра есть интересный пример , который использует устаревшие функции AllocateAndGetTcpExTableFromStack и AllocateAndGetUdpExTableFromStack. Я так понимаю, что сейчас нужно использовать GetExtendedTcpTable, но она не дает информации о размере трафика, прошедшего по соединению. Ну и ладно.

    Теоретически можно было бы как-нибудь синхронизировать время клиента и сервера, отправить сколько-то тестовых данных и посмотреть за сколько они придут.
    Но это помоему тоже какое-то крайнее решение.

    Думал замерить как-то работу WSASend, но как и надо думать - вызов асинхронный, мерить нечего. Причем этот вызов легко проглатывает буферы в 5мб <_<

    Тут я решил подумать, что если я отправляю 1гб, ведь он же не выплевывается весь в сеть, а, насколько я помню, им заполняются небольшие tcp-окна, и пока не придет подтверждение доставки окна, его куски будут отправляться снова и снова.

    Даже если создать еще одно соединение на блокируемых сокетах, будет ли гарантия, что время вызова send-а и есть время посылки или это время копирования данных в буфер какого-то уровня tcp-стека?

    В общем как лучше измерить время отправки данных?

    Может быть стоит как-то довести буфер сокета до переполнения (ведь должна же вернуться ошибка при какой-то огромной передаче?) и периодически досылать туда данные и смотреть сколько влезет и за какое время?

    PS: Время скачивания можно получить путем замера сервером времени передачи и оповещения о результате клиента.
      Цитата SerSEr @
      им заполняются небольшие tcp-окна, и пока не придет подтверждение доставки окна, его куски будут отправляться снова и снова.

      Емнип, макс. размер окна 65кило, кроме того у него переменный размер, также не стоит забывать про сongestion сontrol.

      Добавлено
      Я делал скоростомер целиком интерфейса, разницей между двумя соседними значениями полученных/отправленных байт. Это единственный метод который я знаю. Все остальное, имхо, нереал.
      Цитата
      Может быть стоит как-то довести буфер сокета до переполнения (ведь должна же вернуться ошибка при какой-то огромной передаче?)

      Насколько я знаю, флагами tcp ты управлять не могешь, соот-но выставить DF=1 тоже, значит и переполнить не получится, имхо.
      Сообщение отредактировано: Gonarh -
        Цитата
        Насколько я знаю, флагами tcp ты управлять не могешь, соот-но выставить DF=1 тоже, значит и переполнить не получится, имхо.

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

        Про сongestion сontrol тоже думаю не стоит заморачиваться, потому что затор это более менее нормальная ситуация, можно просто померить несколько раз с каким-то промежутком.

        Цитата
        Я делал скоростомер целиком интерфейса, разницей между двумя соседними значениями полученных/отправленных байт. Это единственный метод который я знаю. Все остальное, имхо, нереал.

        Для этого ты просто загружал соединение какой-то скачкой/закачкой?


        Еще, конечно, хорошо было бы не гнать излишний трафик. Ведь предположим:
        1. Сервер посылает клиенту команду начала теста скорости (все остальные задачи в рамках этого соединения приостанавливаются)
        2. Сервер начинает гнать в сокет 10мб
        3. Клиент получает сообщение начала и начинает принимать данные, замеряя скорость.
        4. Скорость клиента может быть как 4мб/с (выделенка), так и 20кб/с (модем, телефон, итд)
        5. Клиент за минуту принимает 1мб, уже более менее достоверно определяя свою скорость
        6. На сервере в это время где-то в буфере винды остается еще 9мб (!), которые полюбому отправятся и которые клиент должен будет принимать еще ~9 минут.

        Вот как избавиться от последнего пункта?
          Разрывать соединение по таймеру?
            Тоже конечно вариант, но уж очень не вписывается в остальную логику :rolleyes:
              Цитата SerSEr @
              6. На сервере в это время где-то в буфере винды остается еще 9мб (!), которые полюбому отправятся и которые клиент должен будет принимать еще ~9 минут.

              Если клиент оборвет коннект после одной минуты, то send вернёт <= 0, что и будет сигналом завершить прогон данных.
              А по сути вопроса, кмк, ничего лучше прогона инфы в единицу времени не придумать, все эти "спецфункции" - черный ящик.

              Добавлено
              Цитата SerSEr @
              Даже если создать еще одно соединение на блокируемых сокетах, будет ли гарантия, что время вызова send-а и есть время посылки или это время копирования данных в буфер какого-то уровня tcp-стека?

              Время копирования в буфер незначительно, на то он и буфер. А экспериментировать действительно легче на блокирующих.
                В общем все ясно. Спасибо всем за ответы :)
                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0.0628 ]   [ 15 queries used ]   [ Generated: 22.09.26, 13:05 GMT ]