VBScript 检测网络连接是否正常
提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!
某次维护测试需要配置脚本检测网络是否连通,正常手动检测网络是否连通有两个最为常见的办法:一是ping一个主机;二是打开某知名网站。所以脚本检测也顺着这两个思路进行。
关于ping的VBScript实现有 如下代码 可供参考:
Function Ping(strTarget)
Dim objShell, objExec, strPingResults
Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strTarget)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
'WScript.Echo VbCrLf & strTarget & " responded to ping."
Ping = True
Else
'WScript.Echo VbCrLf & strTarget & " did not respond to ping."
Ping = False
End If
Set objExec = Nothing
Set objShell = Nothing
End Function
这段代码很显然通过Command Shell方式执行ping命令,然后获取输出,判断是否有
reply from
,一般情况下这段代码工作良好,但是对于中文Windows来说ping命令有时会返回中文的输出,例如
来自 xxx.xxx.xxx.xxx 的回复...
,为了使得代码兼容,我们必须再判断关键词“的回复”才可以继续正常运行在中文Windows系统下,但这种方式仍然存在风险,尤其是当操作系统更新,也许过几天微软换个花样,那这里判断依然存在失效的风险。因为机器总是呆萌的,只会按照你的既定流程执行,并不会灵活判断。
另外有网友提出了判断命令执行后的返回值,例如下面的代码片段:
Function Ping(strTarget)
Dim objShell, ReturnCode
Set objShell = CreateObject("WScript.Shell")
ReturnCode = oShell.Run("ping -n 1 -w 300 " & strTarget, 0 , True)
If ReturnCode = 0 Then
Ping = True
Else
Ping = False
End If
Set objShell = Nothing
End Function
先前的ping命令通过
-n 2
对目标主机测试了两次,而本次ping命令则通过
-n 1
参数,测试了一次并立即判断返回值,这样做的问题是在一些网络不太稳定的情况下,测试一次的结果往往是不稳定的,也许第一次没有ping通,而第二次和第三次就ping通了,这样我们并不能说网络是不通的。
Michael Bazarewsky 提出了利用WMI的特性实现Ping的方法 ,更增强了脚本的稳定性和兼容性,代码如下:
' This function returns True if the specified host could be pinged.
' strHostName can be a computer name or IP address.
' The Win32_PingStatus class used in this function requires Windows XP or later.
' This function is based on the TestPing function in a sample script by Don Jones
' credit: http://www.robvanderwoude.com/vbstech_network_ping.php
Function Ping(strHostName)
' Standard housekeeping
Dim colPingResults, objPingResult, strQuery
' Define the WMI query
strQuery = "SELECT * FROM Win32_PingStatus WHERE Address = '" & strHostName & "'"
' Run the WMI query
Set colPingResults = GetObject("winmgmts:root\cimv2").ExecQuery(strQuery)
' Translate the query results to either True or False
For Each objPingResult In colPingResults
If Not IsObject(objPingResult) Then
Ping = False
Else
If objPingResult.StatusCode = 0 Then
Ping = True
Else
Ping = False
End If
'WScript.Echo "Ping status code for " & strHostName & ": " & objPingResult.StatusCode
End If
Next
Set colPingResults = Nothing
End Function
好了,Ping的方式检测互联网是否连通是个不错的办法,当然Ping的目标主机可以选择百度(www.baidu.com),或者一些大型的公共DNS服务商,不能选用小众主机哦,万一哪天主机Down了,脚本判断也会出错。
还有一种判断网络是否连通的方式就是网页检测了( 链接 ),但是这种方式会受到ISP的劫持影响,具体代码如下:
Function Ping(strHostName)
Dim objHTTP
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
strURL = "http://" & strHostName
objHTTP.Open "GET", strURL, FALSE
On Error Resume Next
objHTTP.Send
If Err.Number = 0 Then
If objHTTP.statusText = "OK" Then
Ping = True
' MsgBox "Internet is OK"
Else
Ping = False
' MsgBox "Internet not accessible"
End If
Else
Ping = False
' MsgBox "Internet not accessible"
End If
Set objHTTP = Nothing
On Error Goto 0
End Function
所谓的ISP劫持,就是ISP一种推广业务的方式,除了给你弹广告外,还有一种就是当你访问无法访问的页面时会给你自动导向他们的网址导航,可能有网友要问,这也没什么关系吧,至少我证明了网是连通的啊。是的电信级的劫持对于本脚本连接检测影响不大,但是小区宽带也玩劫持的话就有问题了,也许你的主机到小区宽带是连通的,但是这只是一个局域网,小区宽带到Internet并没有连接,那么这样这段脚本的判断也会因此而失效。
其实最需要的是判断目标服务器的指定端口是否能连通。这个用PING不能解决问题 。我用C++写了一个DLL,但是在XP下调用DLL报错。一时没有想到办法解决。
如果要判断指定服务器端口,那么本文所述方法并不可行,此方法仅能检测网络是否连通,判断端口可以采用telnet或者直接使用socket套接字编程。 目前最新的Visual Studio需要配置为兼容XP的模式编译,否则编译的二进制可执行体无法在Windows XP下运行。