Page 3 of 5

Re: Delay-Wait-Sleep tricks.

Posted: 02 Nov 2013 18:29
by Squashman
Magialisk wrote:I'm starting to believe aGerman and jeb, the developers were on some good stuff...

New Mexico desert and too much Peyote.

Re: Delay-Wait-Sleep tricks.

Posted: 02 Nov 2013 18:54
by aGerman
I had to ask Google what Peyote means. It appears that I found that cactus on my window sill :shock: So don't trust my codes in future :lol:

Re: Delay-Wait-Sleep tricks.

Posted: 02 Nov 2013 19:24
by penpen
Magialisk wrote:
penpen wrote:I then have used "ping -n 1 -w 800 1.1.1.1" on A.
I'm sure here you meant to say 192.168.0.11, but BRAVO!
Thanks :D .
But no, i've used 1.1.1.1, as 192.168.0.11 was existing and the running protocols on pc B may answer the ping request automatically.
If that happens it should be much faster than the 800ms, and the ping stops waiting and returns immediately.
The ping program only waits for 800 ms if it does not receive the ping reply.

penpen

Re: Delay-Wait-Sleep tricks.

Posted: 03 Nov 2013 19:48
by Aacini
I think I achieved a milliseconds delay with precise timing when the delay is small. I used an hybrid Batch-JScript solution with WScript.Sleep method, but in order to avoid the load delay of the JScript section each time it is used, both parts must be active at same time. The JScript process take the delay in milliseconds, do the delay and send a signal to the Batch section. The Batch process send the number of milliseconds to JScript and wait for the signal. The way to achieve this bi-directional communication is via JScript's WshShwll.Exec method that have access to Batch process' Stdin and Stdout streams.

Code: Select all

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion
if "%~1" equ "restart" goto secondPart

rem First part: execute JScript section, so it re-execute this Batch file with "restart" parameter
CScript //nologo //E:JScript "%~F0" "%~F0 restart"
goto :EOF

:secondPart

rem To do a delay, use: "echo #millisecs" followed by "set /P ="; use "echo 0" to end
rem To display data in the screen, use:  echo data > CON
rem To read data from keyboard, use set /P "data=Prompt: " < CON > CON

set runs=10
For %%t in (5 10 15 20 30 50 100 250 500 1000) do (

   set time_idle_ms=%%t
   (
   set t0=!time!
   for /L %%p in (1,1,%runs%) do echo %%t& set /P =
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms > CON
)

rem Send the signal to end JScript section
echo 0
goto :EOF


@end


// JScript section

// Restart this Batch file with access to its Stdin and Stdout streams
var WshShell = new ActiveXObject("WScript.Shell");
var BatchFile = WshShell.Exec(WScript.Arguments.Unnamed.Item(0)), delay;

// Get delay, wait and send CR until delay equ 0
while ((delay = BatchFile.Stdout.ReadLine()) != "0" ) {
   WScript.Sleep(delay);
   BatchFile.Stdin.WriteLine();
}


Output:

Code: Select all

Input:5 ms - Output: Average time 15 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 32 ms
Input:30 ms - Output: Average time 31 ms
Input:50 ms - Output: Average time 63 ms
Input:100 ms - Output: Average time 109 ms
Input:250 ms - Output: Average time 263 ms
Input:500 ms - Output: Average time 513 ms
Input:1000 ms - Output: Average time 1014 ms


Antonio

Re: Delay-Wait-Sleep tricks.

Posted: 03 Nov 2013 22:28
by foxidrive
Nice work - Here is what I get in Windows 8.1 32 bit - 3.2 GHz

Code: Select all

Input:5 ms - Output: Average time 14 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 31 ms
Input:30 ms - Output: Average time 32 ms
Input:50 ms - Output: Average time 61 ms
Input:100 ms - Output: Average time 110 ms
Input:250 ms - Output: Average time 250 ms
Input:500 ms - Output: Average time 501 ms
Input:1000 ms - Output: Average time 1000 ms

Re: Delay-Wait-Sleep tricks.

Posted: 04 Nov 2013 08:44
by einstein1969
Aacini wrote:I think I achieved a milliseconds delay with precise timing when the delay is small. I used an hybrid Batch-JScript solution with WScript.Sleep method, but in order to avoid the load delay of the JScript section each time it is used, both parts must be active at same time. The JScript process take the delay in milliseconds, do the delay and send a signal to the Batch section. The Batch process send the number of milliseconds to JScript and wait for the signal. The way to achieve this bi-directional communication is via JScript's WshShwll.Exec method that have access to Batch process' Stdin and Stdout streams.

Code: Select all

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion
if "%~1" equ "restart" goto secondPart

rem First part: execute JScript section, so it re-execute this Batch file with "restart" parameter
CScript //nologo //E:JScript "%~F0" "%~F0 restart"
goto :EOF

:secondPart

rem To do a delay, use: "echo #millisecs" followed by "set /P ="; use "echo 0" to end
rem To display data in the screen, use:  echo data > CON
rem To read data from keyboard, use set /P "data=Prompt: " < CON > CON

set runs=10
For %%t in (5 10 15 20 30 50 100 250 500 1000) do (

   set time_idle_ms=%%t
   (
   set t0=!time!
   for /L %%p in (1,1,%runs%) do echo %%t& set /P =
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms > CON
)

rem Send the signal to end JScript section
echo 0
goto :EOF


@end


// JScript section

// Restart this Batch file with access to its Stdin and Stdout streams
var WshShell = new ActiveXObject("WScript.Shell");
var BatchFile = WshShell.Exec(WScript.Arguments.Unnamed.Item(0)), delay;

// Get delay, wait and send CR until delay equ 0
while ((delay = BatchFile.Stdout.ReadLine()) != "0" ) {
   WScript.Sleep(delay);
   BatchFile.Stdin.WriteLine();
}


Output:

Code: Select all

Input:5 ms - Output: Average time 15 ms
Input:10 ms - Output: Average time 16 ms
Input:15 ms - Output: Average time 15 ms
Input:20 ms - Output: Average time 32 ms
Input:30 ms - Output: Average time 31 ms
Input:50 ms - Output: Average time 63 ms
Input:100 ms - Output: Average time 109 ms
Input:250 ms - Output: Average time 263 ms
Input:500 ms - Output: Average time 513 ms
Input:1000 ms - Output: Average time 1014 ms


Antonio


Great job! This is wonderfull! 8)

I will try as soon as possible because I am very interested in this method.

I was falling back on the "ping" my gateway (to Achieve fast response) or classical vbs script, but this seems even more promising.

Really thanks Aacini! :)


with respect,
Einstein1969

Re: Delay-Wait-Sleep tricks.

Posted: 16 Nov 2013 22:46
by Ed Dyreen
aGerman wrote:
At least we gave the same advice :)

Indeed :lol:
Just one thing I'd like to mention:
1.1.1.1 could be a valid IP address. I would rather use an IP address that belongs to a reserved block.
See http://www.rfc-editor.org/rfc/rfc5737.txt

Code: Select all

>nul ping -n 1 -w 5000 192.0.2.0


Regards
aGerman
Hi aGerman,

why not just ping 0.0.0.0 ? This is an illegal IP not ?

I never had a ping response :roll:

Re: Delay-Wait-Sleep tricks.

Posted: 17 Nov 2013 04:58
by aGerman
It is a valid IP address and it will be resolved to the local host name.
Try
ping -a 0.0.0.0
or
netstat -a

0.0.0.0 represents all IP addresses on the local machine. That's the reason why ping fails.

Regards
aGerman

Re: Delay-Wait-Sleep tricks.

Posted: 17 Nov 2013 06:29
by penpen
There are some cases in which addresses like 0.0.0.0 are producing pings:
some are implementation errors of drivers (http://serverfault.com/questions/415784/why-and-or-how-is-something-to-replying-to-pings-as-0-0-0-0),
some are side effects from aliasing all unknown addresses to a predefined one,
and some (hardware) network monitors may respond to such an icmp ping request.

So you cannot be sure that a ping request will fail on a specific address.

The best solution is to define an ip adress in your network (class) (for example class C network: 192.0.0.0 to 223.255.255.255) that is forbidden to be used e.g. 192.168.0.254, and ping this (unused) ip address (NATs should be configured to filter out the pings).

penpen

Edit: But if the pc received a ping response, then it would not wait, too (same result as if ping fails: not waiting for the specified delay).

Re: Delay-Wait-Sleep tricks.

Posted: 18 Nov 2013 12:01
by carlos
I do some investigations and I found that the default values for ping in these options are the next (under xp):

Code: Select all

-l 32
-w 4000


Thn this is my code for do a delay in milliseconds:

replace "milliseconds" for the value

Code: Select all

ping -l 0 -n 1 -w milliseconds 1.0.0.0


Edited: I changed the ip for compatibility with Windows 8.

Re: Delay-Wait-Sleep tricks.

Posted: 18 Nov 2013 13:19
by carlos
In Windows 8 0.0.0.0 is invalid. From 1.0.0.0 I can get the requested timeout for do the delay specified in -w option

in Windows 8:

C:\>ping -l 0 -n 1 -w 300 0.0.0.0

Pinging 0.0.0.0 with 0 bytes of data:
PING: transmit failed. General failure.

Ping statistics for 0.0.0.0:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 0.0.0.1

Pinging 0.0.0.1 with 0 bytes of data:
PING: transmit failed. General failure.

Ping statistics for 0.0.0.1:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 1.0.0.0

Pinging 1.0.0.0 with 0 bytes of data:
Request timed out.

Ping statistics for 1.0.0.0:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -l 0 -n 1 -w 300 1.1.1.1

Pinging 1.1.1.1 with 0 bytes of data:
Request timed out.

Ping statistics for 1.1.1.1:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

Re: Delay-Wait-Sleep tricks.

Posted: 18 Nov 2013 13:22
by carlos
In Windows 8 and Windows XP: 0.0.0.0 produce General failure.
In Windows 8 0.0.0.1 produce General failure.
In Windows XP 0.0.0.1 produce Requested timeout.

There are a difference.

In windows 8 the valid ips for do a timeout are from: 1.0.0.0

Re: Delay-Wait-Sleep tricks.

Posted: 27 Nov 2013 15:20
by einstein1969
I post this function here, because often you use the time to calculate the elapsed time.

The variable %time% return a value in hundredths of a second but every little commits an error.

This function show the ERROR that there are in the get time of batch dos.

Show the number of GAP in the set returned.

Code: Select all

@echo off
rem detect where is the error!
setlocal EnableDelayedExpansion

echo Sync...to 00 or 01 %time%
:loopm100
if "%time:~-2%" neq "00" if "%time:~-2%" neq "01" goto :loopm100
echo %time%
echo(


set "st="
set ot=!time!
set obg=!ot!
set g2=0
:loop1100
(
  if "!time!" equ "!ot!" goto :loop1100
  set t=!time!
  set /a "d=1!t:~-2!-1!ot:~-2!, d+=(d>>31) & 100"
  if !d! gtr 1 if !d! equ 2 (set /a g2=g2+1) else (
   for /F "tokens=1-8 delims=:.," %%a in ("!obg: =0!:!ot: =0!") do set /a "db=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, db+=(db>>31) & 8640000, db+=d"
   echo Gap at !ot! + !d! = !t! [!g2! of 2] from !obg! [+!db!]
   set g2=0
   set obg=!t!
  )
  set ot=!t!
goto :loop1100
)


result:

Code: Select all

Gap at 22:13:43,64 + 3 = 22:13:43,67 [0 of 2] from 22:13:39,00 [+467]
Gap at 22:13:48,59 + 4 = 22:13:48,63 [1 of 2] from 22:13:43,67 [+496]
Gap at 22:13:53,19 + 10 = 22:13:53,29 [1 of 2] from 22:13:48,63 [+466]
Gap at 22:13:55,64 + 3 = 22:13:55,67 [0 of 2] from 22:13:53,29 [+238]
Gap at 22:14:02,45 + 3 = 22:14:02,48 [2 of 2] from 22:13:55,67 [+681]
Gap at 22:14:06,99 + 12 = 22:14:07,11 [0 of 2] from 22:14:02,48 [+463]
Gap at 22:14:12,64 + 4 = 22:14:12,68 [1 of 2] from 22:14:07,11 [+557]
Gap at 22:14:16,20 + 7 = 22:14:16,27 [1 of 2] from 22:14:12,68 [+359]
Gap at 22:14:16,27 + 3 = 22:14:16,30 [0 of 2] from 22:14:16,27 [+3]
Gap at 22:14:25,49 + 22 = 22:14:25,71 [2 of 2] from 22:14:16,30 [+941]
Gap at 22:14:30,24 + 14 = 22:14:30,38 [0 of 2] from 22:14:25,71 [+467]
Gap at 22:14:38,64 + 5 = 22:14:38,69 [2 of 2] from 22:14:30,38 [+831]
Gap at 22:14:41,64 + 6 = 22:14:41,70 [0 of 2] from 22:14:38,69 [+301]


There are gap where the time jump of 2. This function detect jump of 2 and >2

The jump of 2 are only counted. The jump >2 are show in each line.

Also measured the time since the last jump / gap >2

EDIT: why this analisys? because there are some schemes in the result! If you open an application the gaps increase. Even if you run in realtime!


Einstein1969

Re: Delay-Wait-Sleep tricks.

Posted: 28 Nov 2013 10:33
by einstein1969
Hi,
The best solution seems to be to use jscript or with some limitations with jscript in the pipe, but I still wanted to not let this opportunity with ping.

I had seen this method in the past and I reimplemented. It works with a router connected.
Use Ping to the router with big packet size to get a greater delay and therefore a lower CPU consumption.

It is not very accurate, but on my pc uses only 30-40% of cpu.
We can do better?

Code: Select all

@echo off & setlocal EnableDelayedExpansion

call :discovery_router router
echo Using %router% ...

For %%t in (5 50 100 200 250 500 1000 1500) do (

   set time_idle_ms=%%t
   set runs=100
   (
   set t0=!time!
   for /L %%p in (1,1,!runs!) do call :fake_ping !time_idle_ms! %router%
   set t1=!time!
   )

   for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

   set /a average_time=a*10/runs
   echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms
)

goto :eof

:discovery_router rem find router
  setlocal
  set "router="
  for /f "tokens=* delims=" %%f in ('tracert -d -h 1 -w 1 whatismyipaddress.com ^| find "ms"') do set "router=%%f"
  set "router=%router:~30%"
  if not defined router goto :discovery_router
  rem echo(router=!router!
  endlocal & set %1=%router%
goto :eof

:fake_ping %delay%ms %router%
setlocal
   set t0=%time%
:loop_fake_ping
   ping %~2 -n 1 -w 1 -l 32768 >nul
   for /F "tokens=1-8 delims=:.," %%a in ("%t0: =0%:%time: =0%") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000, a=a*10+20"
   if %a% lss %~1 goto :loop_fake_ping
   rem echo %t0% - %time% %a% [%1 %2]
endlocal
goto :eof


result: on windows 7 Mono processor

Code: Select all

Using   192.168.200.1  ...
Input:5 ms - Output: Average time 58 ms
Input:50 ms - Output: Average time 64 ms
Input:100 ms - Output: Average time 121 ms
Input:200 ms - Output: Average time 209 ms
Input:250 ms - Output: Average time 268 ms
Input:500 ms - Output: Average time 529 ms
Input:1000 ms - Output: Average time 1022 ms
Input:1500 ms - Output: Average time 1502 ms


EDIT : I have added a fix to compensate the error on %TIME%

Einstein1969

Re: Delay-Wait-Sleep tricks.

Posted: 11 Jan 2014 15:53
by einstein1969
Hi,

I have investigate on %time%.

The time is incremented every 15 or 16 millisecond.

Can anyone explain why?

This explain why there is a gap between centiseconds.

We can predict the error!

EDIT: the interval is near 15,65 ms

Einstein1969