уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Думаю, что редко кто в Рунете не знает такой замечательный сервис как pr-cy.ru? У кого-то в свое время родилась отличная идея — создать сайт на котором собраны все инструменты, которые могу когда-либо потребоваться web-мастеру. В числе прочих полезных инструментов у pr-cy.ru есть инструмент Проверка скорости интернета. Хорошая вещь. Определяет скорость подключения, причем делает это максимально точно. В целом работа инструмента «Проверка скорости интернета» достаточно проста и одновременно эффективна. И вот, что я подумал: а почему бы не создать что-либо подобное (я имею ввиду сопоставимое по скорости и качеству работы), но только в Delphi? Как это у меня в последнее время повелось — я решил снова поразбираться в библиотеке Synapse — может там что-нибудь есть для решения задачи? Но сначала немного предыстории вопроса.


По сути вопрос «Как измерить скорость Интернета?» я считаю некорректным. Более правильно было бы спросить «Как узнать скорость подключения к ресурсу в Интернет?» или «Как узнать скорость закачки файла?» и т.д. Чтобы понять как используются казалось бы одни и те же величины — килобиты и килобайты при измерении скоростей в Интернет и объемов данных я изучил (и Вам советую) статью от Артемия Лебедева «Сколько байтов в килобайте?«, где достаточно доступно и подробно описываются все различия, например между кбайт и Кбайт и т.д..
Поэтому вначале я решил проверить две величины:
1. Скорость загрузки файла с какого-либо сайта
2. Время ответа сервера (ping)
Определить скорость загрузки можно, например, так: берем файл определенного размера  и пробуем его скачать. По времени, затраченному на скачивание определим скорость загрузки данных (входящую) в Кбайт/сек.
Здесь появляется один небольшой вопрос:  как измерить время затраченное на операцию.  Тут можно рассуждать, экспериментировать вплоть до использования ассемблера и измерения количества тактов ЦП. Я вначале тоже хотел воспользоваться по старинке функцией GetTickCount, но потом решил не повторяться и воспользоваться двумя другими функциями из той же библиотеки kernel32.dll.
Итак вначале о том, как мы измерим время. Нам понадобятся всего две функции:
QueryPerformanceCounter — возвращает текущее значение счетчика с высоким разрешением производительности
QueryPerformanceFrequency — возвращает частоту счётчика count/sec.
То есть для того, чтобы измерить время какой-либо операции, а в нашем случае — это время загрузки файла, нам надо будет сделать так:

var iCounterPerSec: TLargeInteger;
     T1, T2: TLargeInteger; //значение счётчика ДО и ПОСЛЕ операции
begin
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(T1);
 
{тут скачиваем файл}
 
  QueryPerformanceCounter(T2);
  ShowMessage(FormatFloat('0.0000', (T2 - T1) / iCounterPerSec) + ' сек.');

Теперь рассмотрим следующий шаг — загрузку файла. Используя Synapse можно пойти двумя простыми путями:
1. Загружать определенный файл, который лежит всё время на одном месте. Для этого можно использовать функцию из модуля httpsend.pas HttpGetBinary.
2. Скачать страницу сайта и по скачанному объему данных судить о скорости. Здесь можно воспользоваться либо функцией HttpGetText из того же модуля, либо задействовать объект THTTPSend.
Дополнительно с помощью Synapse мы можем организовать и пинг сервера, используя модуль pingsend.pas, Реализуем всё вышесказанное на примере.
Создадим новое приложение Delphi и подключем в uses два модуля httpsend и pingsend. Будем определять скорость загрузки и время ответа сервера. Внешний вид программы может быть примерно таким:

И теперь несколько замечаний по поводу работы программы. Для того, чтобы как можно точнее измерять скорость желательно иметь под рукой файл подходящего размера. К примеру, если мне провайдер обещает 14,4 Кбайт/сек на загрузку, то мне желательно качать файлик больше 14 Кбайт. С другой стороны, чем больше файл — тем больше времени будет затрачено на его загрузку и, следовательно, программа будет дольше «висеть». Я решил ограничиться файлом размером около 800 Кбайт — архивом с wpchecker, который как раз-таки и лежит у меня в блоге.
Код обработчика onClick кнопки у меня получился такой:

procedure TForm2.Button1Click(Sender: TObject);
var iCounterPerSec: TLargeInteger;
    C1, C2: TLargeInteger;
    Stream: TMemoryStream;
begin
{Пинг}
  label7.Caption:=IntToStr(PingHost(Edit1.Text))+' мс.';
{качаем файл}
  Stream:=TMemoryStream.Create;
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(C1);
  HttpGetBinary('http://webdelphi.ru/wp-content/uploads/2010/02/wpchecker.zip',Stream);
  QueryPerformanceCounter(C2);
  label8.Caption:=FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' сек.';
  label10.Caption:=CurrToStr(Stream.Size/1024);
  label11.Caption:=CurrToStr((Stream.Size/1024)/((C2 - C1) / iCounterPerSec))+' кбайт/сек'
end;

Проверим, не врет ли мой провайдер на счёт 14,4 Кбайт/сек:

Как видно из рисунка — не врет. Если учесть также, что в момент теста у меня запущен браузер, работает Твиттер-клиент, антивирус обновляется и т.д., то реальная скорость даже повыше. И это, кстати, следует учитывать: в момент теста желательно завершить все процессы, которые так или иначе используют тестируемое Интернет-соединение. Как видите тест загрузки файла оказался элементарным. Аналогично можно выполнить и тест исходящей скорости, только для этого нам потребуется место в Сети, куда можно залить файл и функция Synapse HttpPostBinary.
В заключение могу добавить, что в Windows есть замечательная библиотека IpHlpAPI.dll, используя функции которой можно определять скорости подключений, количество входящего/исходящего трафика и т.д. К сожалению в составе Delphi нет готового модуля с заголовками функций из этой библиотеки, но некоторые модули для работы с библиотекой были доступны на delphi-jedi.org. Но скорость соединения — это уже другая тема :)

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
9 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
13-ый
26/04/2010 00:45

кстати, сервис измерения скорости есть н-р у яндекса

http://internet.yandex.ru/

скорость скачивания : 12072 Кбит/с
скорость закачки : 11618 Кбит/с

Vayrus
Vayrus
27/04/2010 08:10

Привет, очень интересные статьи, спасибо. Особенно радует реализация на Synapse.

PS
Конечно неплохо было бы все это дело оформить в поток и предусмотреть кнопку Отмена.
Я лично плохо в них разбираюсь и хотел бы чтобы Вы это продемонстрировали с помощью спец модуля для создания многопоточных приложений (любого, который есть например на torry.net).

Vayrus
Vayrus
27/04/2010 13:04

Спасибо

Макс
Макс
26/08/2010 18:01

Твой способ не корректен так как показывает НЕ реальную скорость а среднюю скорость закачки какого то файла с КАКОГОТО сервера (почему какого-то, да потому что может быть бесчисленное множество причинпо которым эта скорость правильна для закачки этого файла но далека от реальной скорости соединения которая используется в данный момент ) Попробуй использовать WinAPI функцию GetIfTable тогда точно получишь текущую точную скорость соединения по указанному тобой интерфейсу(то бишь Сетевой карточке) вот так примерно у меня работает procedure TForm1.Timer1Timer(Sender: TObject); var _MibIfTable:PMibIfTable; _P:Pointer; i:integer; _buflen:dword; _error:dword; begin listview1.Items.Clear; _buflen:=sizeof(_MibIfTable^); New(_MibIfTable); _P:=_MibIfTable; _error:=GetIfTable(_MibIfTable, @_buflen, false); if _error NO_ERROR then begin ShowMessage(‘Произошла ошибка!’); Exit;… Подробнее »

SeregaAltmer
28/08/2010 01:24

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

Влад писал: «По сути вопрос “Как измерить скорость Интернета?” я считаю некорректным. Более правильно было бы спросить “Как узнать скорость подключения к ресурсу в Интернет?” или “Как узнать скорость закачки файла?” и т.д.»
Абсолютно с ним согласен.
Да и пост как раз про «скорость подключения к ресурсу», даже в шапке написано: «Самый простой способ узнать скорость загрузки файла из Сети». А GetIfTable следует использовать, как ты и указал, для расчета скорости соединения по указанному интерфейсу.

Так-что тема полностью раскрыта :)

trackback
Synapse. Работа с прокси. | Delphi в Internet
06/01/2014 05:56

[…] Кстати, ещё одним немаловажным моментом является время ответа сервера. Если используется proxy, то время на выполнение запроса неизбежно возрастает и иногда значительно, поэтому важно иметь под рукой не список не только рабочих, но и быстрых прокси. Время выполнения запроса в Delphi оценить просто, например, используя материалы одного из постов, посвященных Synapse. […]

Alexey Pikurov
12/11/2015 19:21

2. Скачать страницу сайта и по скаченному объему данных судить о скорости
[Grammar Nazi mode on]
Влад, скачАнный. Поправь пожалуйста, глаз режет.
[Grammar Nazi mode off]