[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[网络连接] [已解决]自编检测网络状况的批处理代码,为什么时间一长程序会自动终止?

本帖最后由 小胖狐狸 于 2011-12-9 10:38 编辑

前几天单位的网络出现故障,我试图写个批处理时刻运行,检测网络状况
两个问题:
1、实际应用发现长时间执行该批处理,会自动终止,请教为什么,如何解决?
2、这个批处理本来在for语句中,我是调用两个函数do1和do2,后来发现语句类似,就设法将两个函数合并了,但是实际应用中发现合并前,该批处理执行时占用内存为1M多,合并后占用2M多,请问如何让批处理尽量少的占用内存?——现在是代码看似简洁了,占内存反而多了
补充:刚刚才发现,这个批处理在执行的时候,居然每秒钟占用内存量都会增加50K左右,发帖到现在已经9M多了……现在我猜到为什么会自动终止了

工作原理简单说明:
默认ping www.baidu.com的联通状况,如果连接状态发生变化,则写入日志文件,并检测另外两个连接状态
文中涉及的IP_url.txt内容如下,文中涉及的log日志文件供写入
  1. 检查以下特定网络地址的连通性
  2. 局域网网关:192.168.1.1
  3. 百度IP:61.135.169.125
  4. 百度URL:www.baidu.com
复制代码
  1. 备注:退格符此处无法显示 set 退格=
  2. @echo off&setlocal enabledelayedexpansion
  3. color 0A
  4. cls
  5. mode con: cols=50 lines=4
  6. :: 通讯正常时 status=1,异常时 status=0;
  7. set status1=1
  8. set status2=1
  9. set status3=1
  10. set skipnum=3
  11. set connect1=通讯正常
  12. set connect0=通讯异常
  13. set connectS1=恢复连接
  14. set connectS0=无法连接
  15. set 退格=
  16. echo.>>ConnectError.Log
  17. echo.>>ConnectError.Log
  18. echo ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓>>ConnectError.Log
  19. echo ┃%date% %time:~,-3% 开始监控指定IP地址的连通状况 ┃>>ConnectError.Log
  20. echo ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛>>ConnectError.Log
  21. echo.>>ConnectError.Log
  22. :detect
  23. ::判断配置文件IP_url.txt中指定IP地址是否能ping通
  24. for /f "delims=: tokens=1,2 skip=%skipnum%" %%i in (IP_url.txt) do (
  25. set var_ip=%%j
  26. set var_n=%%i
  27. ping -n 1 -l 1 -w 1 !var_ip!|find /i "TTL=">nul &&call :do 1 0 3||call :do 0 1 1
  28. )
  29. :do
  30. ::根据不同状况改变颜色
  31. if %1 equ 1 (color 0A) else (color EC)
  32. ::设置屏显及闪动●
  33. set var1=%1
  34. set /p a=%退格%<nul
  35. set /p a=    <nul
  36. ping -n 1 127.1>nul
  37. set /p a=%退格%<nul
  38. set /p a= ●   !var_n! !var_ip! !connect%var1%!      <nul
  39. ::如果连通状态有变化,则写入日志
  40. if !status%skipnum%! equ %2 (
  41. set status%skipnum%=%1
  42. echo %date% %time:~,-3% !var_n! !var_ip! !connectS%var1%!>>ConnectError.Log
  43. )
  44. if %1 equ 1 (if %skipnum% lss 3 (set /a skipnum=%random%%%3+1)) else (if %skipnum% gtr 1 (set /a skipnum=%random%%%3+1))
  45. call :delay2&&goto :detect
  46. :delay2
  47. ping -n 3 127.1>nul
复制代码
1

评分人数

    • CrLf: 感谢给帖子标题标注[已解决]字样PB + 2

自己使用版

@echo off&setlocal enabledelayedexpansion
color 0A
cls
mode con: cols=60 lines=6
:detect
ping -n 3 www.baidu.com |findstr "TTL="
echo.
echo      %date% %time%
if "%errorlevel%"=="1"  (msg * /w 提示:网络断了)
ping -n 60 127.0.0.1>nul
cls
goto :detect
echo else (msg * /w 提示:网络OK)

TOP

本帖最后由 pk987 于 2012-12-24 14:51 编辑

这二天,我也在找 批处理检测网络,在这里没找到合适的。
就自己写了个简单的(最后一句可有可无,是if后面,检测到网络正常时跳出提示)。

@echo off
:detect
ping -n 3 www.baidu.com |findstr "TTL="
if "%errorlevel%"=="1"  (msg * /w 提示:网络断了)
ping -n 50 127.0.0.1>nul
cls
goto :detect
echo else (msg * /w 提示:网络OK)

----为了美观,还可以把第一行,换成下面四行
@echo off&setlocal enabledelayedexpansion
color 0A
cls
mode con: cols=60 lines=6

TOP

罪魁祸首也许是这一句:
  1. set status%skipnum%=%1
复制代码
如果任由变量不加节制地增长,将出现内存占用持续增长、运行效率渐低的现象,最终 cmd.exe 占用内存超过 64 兆时将崩溃(不过极少发生)。
另外,由于ping.exe和findstr.exe均为外部命令,所以不建议在循环中大量使用,将会影响脚本的效率和资源占用,所以可以换个思路,先 ping 一轮,然后对比前后两次 arp -a 的输出,其中消失的就是 ping 不到的,多出的就是新 ping 到的。
还有一个思路,如果要检查的列表中只有少数几个 ip 的话,也可以 start /b ping /t %%a>%%a.txt,接下来用 "for %%a in (*.txt) do for /f "skip=上次的行数" %%b in ('type %%b') do " 来检查这几个 txt 就行了,这样避免了频繁开启新进程的缺陷。

TOP

感谢
加了个计数,不要死循环了

TOP

回复 3# 小胖狐狸


死循环本身太浪费系统资源了

TOP

如果一直执行的话,占用CPU和内存是很正常的,可以参考2L的想法,
1

评分人数

    • CrLf: 乐于助人PB + 3
枫中残雪:风停了,我的心却在动,让我心中的寒意走向远方

TOP

回复 2# awk


    可以是可以,一般不建议批处理用死循环吗?

TOP

不要写成死循环,放到任务计划里面每几分钟运行一次,这样可以吗?
1

评分人数

    • CrLf: 乐于助人PB + 5

TOP

返回列表