Obsidian-step, я так понял, вам нужно замерять не текущую скорость соединения, как это сделано в посте #15, а приблизительную максимальную в один поток, так ведь? Иначе, при простое, когда соединение будет нагружено меньше 50кб\с, оно будет постоянно перезапускаться.
Вот, написал кое-что. Для работы требует wget, все тот же calc.exe из набора утилит gnuwin32 (переименованый в gnucalc.exe) и nircmd. Все должно лежать в директории bin рядом со скриптом.
Скачать требуемые файлы с RGhost
Требования к файлу для проверки скорости: должен располагаться на быстром сервере (чтобы измерение не упиралось в максимальную скорость отдачи на 1 поток самого сервера), должен быть размером не менее 1 мб (а желательно - от 2 до 10) для обеспечения приемлемой точности.
Код:
@Echo Off
:: Добавляем директорию с бинарниками в path
Echo %Path%|Find "%CD%\bin">nul||Set Path=%Path%;%CD%\bin
:: Период обновления, в минутах
Set Refresh=2
:: Устанавливаем файл для проверки (2-10 мб, на быстром хосте)
Set SpeedTestFile=http://support.satgate.net/dl_test/dl/5MB.bin
:: Нижний порог скорости, при опускании ниже этого предела - реконнект сети. (В кб\с)
Set MinSpeed=50
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set StartedAt=%ErrorLevel%
Set Timestamp=%date% %time:~-0,8%
Set /A Refresh=Refresh*60*1000
:Loop
:: Замеряем время
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set StartDL=%ErrorLevel%
:: Получаем файл
wget %SpeedTestFile% -O "%Temp%\speedtest.dat" 1>&2 2>nul||(Call :Reconnect&GoTo Loop)
:: Получаем его размер (получение размера напрямую, через переменную - не работает)
For /F "tokens=*" %%A In ('Dir "%Temp%\speedtest.dat" /A-D^|Find "speedtest.dat"') Do (
For /F "tokens=3" %%S In ("%%A") Do (Set TestFileSize=%%S)
rem Del %Temp%\speedtest.dat
)
:: Вырезаем псевдопробелы
Set TestFileSize=%TestFileSize:я=%
:: Получаем затраченное на скачивание время
Call :Timer %StartDL%
Set DLTime=%ErrorLevel%
:: Рассчитываем скорость
SetLocal EnableDelayedExpansion
For /F "tokens=*" %%A In ('gnucalc ^(%TestFileSize%/1024^)/%DLTime%') Do (
For /F "tokens=1,2 delims=." %%A In ("%%A") Do (
Set tmpA=%%A
If "!tmpA:~,1!"=="~" Set tmpA=!tmpA:~1!
If "!tmpA:~,1!"=="-" Set tmpA=!tmpA:~1!
Set tmpB=%%B
If "!tmpB:~,1!"=="~" Set tmpB=!tmpB:~1!
If "!tmpB:~,1!"=="-" Set tmpB=!tmpB:~1!
If "!tmpB!"=="" Set tmpB=0
Set tmpB=!tmpB:~,2!
Set DisplayedSpeedKBs=!tmpA!.!tmpB!
If !tmpB! GEQ 50 Set /A tmpA+=1
Set SpeedKBs=!tmpA!
)
)
:: Проверяем, не слишком ли низкая скорость
If %SpeedKBs% LSS %MinSpeed% (Call :Reconnect&GoTo Loop)
:: Выводим состояние
Call :Timer %StartedAt%
Call :DeserializeTime %ErrorLevel%
Cls
Title Download speeed: %DisplayedSpeedKBs% Kb\s
Echo Started at : %Timestamp%
Echo Elapsed time : %ED% days, %DHH%:%DMM%:%DSS%
Echo Connection speed : %DisplayedSpeedKBs% Kb\s
NircmdC wait %Refresh%
GoTo Loop
:: Перезапуск сети
:Reconnect
netsh interface set interface local disabled
netsh interface set interface local enabled
Exit /B
::===Функции работы со временем в .bat====================================
:: libTime.cmd, Anonymous, 2010
:ParseTimestamp
:: Разбирает на составляющие временную метку формата ЧЧ:ММ:СС
:: Формат: Call :ParseTimestamp (время)
:: Вывод - в переменные HH MM и SS
For /F "tokens=1,2,3 delims=:" %%A In ("%1") Do (
Set HH=%%A
Set MM=%%B
Set SS=%%C
)
:SerializeTime
:: Сериализует время из переменных HH MM и SS
:: Вывод - в ErrorLevel
Set /A STime=(HH*60*60)+(MM*60)+SS
Exit /B %STime%
:DeserializeTime
:: Десериализует время, приводит его к стандартному формату
:: Формат: Call :DeserializeTime (сериализованное время)
:: Вывод - в переменные DHH DMM и DSS
Set /A DHH=%1/60/60
Set /A DMM=(%1/60)-(DHH*60)
Set /A DSS=%1-(DHH*60*60)-(DMM*60)
If %DHH%==24 Set DHH=00
If %DHH% LSS 10 Set DHH=0%DHH%
If %DMM% LSS 10 Set DMM=0%DMM%
If %DSS% LSS 10 Set DSS=0%DSS%
Exit /B
:TMinus
:: Функция вычитания для сериализованного времени
:: Формат: Call :TMinus (сериализованное время) (сколько секунд отнять)
:: Вывод - в ErrorLevel
Set /A Result=%1-%2
If %2 GTR %1 (
Set /A Result=86400+%1-%2
)
Exit /B %Result%
:TPlus
:: Функция прибавления для сериализованного времени
:: Формат: Call :TPlus (сериализованное время) (сколько секунд прибавить)
:: Вывод - в ErrorLevel
Set /A Result=%1+%2
If %Result% GTR 86400 (
Set /A Result=%1+%2-86400
)
Exit /B %Result%
:Timer
:: Отсчитывает прошедшее с заданного момента время
:: Формат: Call :Timer (запомненное сериализованное время)
:: Вывод - в ErrorLevel
:: Если счетчик переходит границу суток, число дней возрастает на 1
:: Дни выводятся в переменную ED (и накапливаются) // да, знаю, что костыль и быдлокод
Set OTime=%1
If "%ED%"=="" Set ED=0
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Set CTime=%ErrorLevel%
If %OTime% GTR %CTime% (
Set /A Timer=86400-%OTime%+%CTime%
Set /A ED+=1
) Else (
Set /A Timer=CTime-OTime
)
Exit /B %Timer%
:Timer2
:: Проверяет, прошел ли заданный промежуток времени
:: Формат: Call :Timer2 (запомненное сериализованное время) (промежуток в секундах)
:: Вывод - в ErrorLevel (только 0=промежуток истёк или 1=промежуток ещё не истёк)
Call :ParseTimestamp %time:~-0,8%
Call :SerializeTime
Call :TMinus %ErrorLevel% %1
If %2 GTR %ErrorLevel% Exit /B 1
Exit /B 0
::========================================================================