Думаю, что редко кто в Рунете не знает такой замечательный сервис как 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. Но скорость соединения — это уже другая тема :)
кстати, сервис измерения скорости есть н-р у яндекса
http://internet.yandex.ru/
скорость скачивания : 12072 Кбит/с
скорость закачки : 11618 Кбит/с
Неповерите, но пробовал этот сервис в 3-х разных браузерах ответ был один «Несмогли определить скорость зайдите через 15 минут» поэтому забил я на него болт :)
Привет, очень интересные статьи, спасибо. Особенно радует реализация на Synapse.
PS
Конечно неплохо было бы все это дело оформить в поток и предусмотреть кнопку Отмена.
Я лично плохо в них разбираюсь и хотел бы чтобы Вы это продемонстрировали с помощью спец модуля для создания многопоточных приложений (любого, который есть например на torry.net).
Так в блоге есть целых два поста посвященных потокам, правда там Серега рассматривал поток с WinInet, но думаю, что под Synapse переделать будет просто. Вот ссылки:
http://www.webdelphi.ru/2009/10/mnogopotochnost-v-svoix-prilozheniyax/
http://www.webdelphi.ru/2009/10/mnogopotochnost-v-svoix-prilozheniyax-chast-2/
Спасибо
Твой способ не корректен так как показывает НЕ реальную скорость а среднюю скорость закачки какого то файла с КАКОГОТО сервера (почему какого-то, да потому что может быть бесчисленное множество причинпо которым эта скорость правильна для закачки этого файла но далека от реальной скорости соединения которая используется в данный момент ) Попробуй использовать 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;… Подробнее »
Макс, ТТаймер отсчитывает интервал от завершения предыдущего события до вызова следующего. Поэтому для точного замера скорости нельзя на него полагаться.
Влад писал: «По сути вопрос “Как измерить скорость Интернета?” я считаю некорректным. Более правильно было бы спросить “Как узнать скорость подключения к ресурсу в Интернет?” или “Как узнать скорость закачки файла?” и т.д.»
Абсолютно с ним согласен.
Да и пост как раз про «скорость подключения к ресурсу», даже в шапке написано: «Самый простой способ узнать скорость загрузки файла из Сети». А GetIfTable следует использовать, как ты и указал, для расчета скорости соединения по указанному интерфейсу.
Так-что тема полностью раскрыта :)
[…] Кстати, ещё одним немаловажным моментом является время ответа сервера. Если используется proxy, то время на выполнение запроса неизбежно возрастает и иногда значительно, поэтому важно иметь под рукой не список не только рабочих, но и быстрых прокси. Время выполнения запроса в Delphi оценить просто, например, используя материалы одного из постов, посвященных Synapse. […]
2. Скачать страницу сайта и по скаченному объему данных судить о скорости
[Grammar Nazi mode on]
Влад, скачАнный. Поправь пожалуйста, глаз режет.
[Grammar Nazi mode off]