请问如何用VB实现从本地计算机向远程网络设备发出"ping"指令?

解决方案 »

  1.   

    放置一个按钮,6个文本
    Option ExplicitPrivate Declare Function IcmpCreateFile Lib "icmp.dll" () As Long
    Private Declare Function IcmpCloseHandle Lib "icmp.dll" (ByVal IcmpHandle As Long) As Long
    Private Declare Function IcmpSendEcho Lib "icmp.dll" (ByVal IcmpHandle As Long, ByVal DestinationAddress As Long, ByVal RequestData As String, ByVal RequestSize As Long, ByVal RequestOptions As Long, ReplyBuffer As ICMP_ECHO_REPLY, ByVal ReplySize As Long, ByVal Timeout As Long) As Long
    Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long
    Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired As Long, lpWSADATA As WSADATA) As Long
    Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long'  ICMP返回的报文信息常数和Winsock版本等相关常数
    Private Const IP_STATUS_BASE = 11000
    Private Const IP_SUCCESS = 0
    Private Const IP_BUF_TOO_SMALL = (11000 + 1)
    Private Const IP_DEST_NET_UNREACHABLE = (11000 + 2)
    Private Const IP_DEST_HOST_UNREACHABLE = (11000 + 3)
    Private Const IP_DEST_PROT_UNREACHABLE = (11000 + 4)
    Private Const IP_DEST_PORT_UNREACHABLE = (11000 + 5)
    Private Const IP_NO_RESOURCES = (11000 + 6)
    Private Const IP_BAD_OPTION = (11000 + 7)
    Private Const IP_HW_ERROR = (11000 + 8)
    Private Const IP_PACKET_TOO_BIG = (11000 + 9)
    Private Const IP_REQ_TIMED_OUT = (11000 + 10)
    Private Const IP_BAD_REQ = (11000 + 11)
    Private Const IP_BAD_ROUTE = (11000 + 12)
    Private Const IP_TTL_EXPIRED_TRANSIT = (11000 + 13)
    Private Const IP_TTL_EXPIRED_REASSEM = (11000 + 14)
    Private Const IP_PARAM_PROBLEM = (11000 + 15)
    Private Const IP_SOURCE_QUENCH = (11000 + 16)
    Private Const IP_OPTION_TOO_BIG = (11000 + 17)
    Private Const IP_BAD_DESTINATION = (11000 + 18)
    Private Const IP_ADDR_DELETED = (11000 + 19)
    Private Const IP_SPEC_MTU_CHANGE = (11000 + 20)
    Private Const IP_MTU_CHANGE = (11000 + 21)
    Private Const IP_UNLOAD = (11000 + 22)
    Private Const IP_ADDR_ADDED = (11000 + 23)
    Private Const IP_GENERAL_FAILURE = (11000 + 50)
    Private Const MAX_IP_STATUS = 11000 + 50
    Private Const IP_PENDING = (11000 + 255)
    Private Const PING_TIMEOUT = 200
    Private Const WS_VERSION_REQD = &H101
    Private Const WS_VERSION_MAJOR = WS_VERSION_REQD \ &H100 And &HFF&
    Private Const WS_VERSION_MINOR = WS_VERSION_REQD And &HFF&
    Private Const MIN_SOCKETS_REQD = 1
    Private Const SOCKET_ERROR = -1
    Private Const MAX_WSADescription = 256
    Private Const MAX_WSASYSStatus = 128'   ICMP选项结构
    Private Type ICMP_OPTIONS
        Ttl             As Byte
        Tos             As Byte
        Flags           As Byte
        OptionsSize     As Byte
        OptionsData     As Long
    End Type'   ICMP应答结构
    Private Type ICMP_ECHO_REPLY
        Address         As Long
        status          As Long
        RoundTripTime   As Long
        DataSize        As Long
        DataPointer     As Long
        Options         As ICMP_OPTIONS
        Data            As String * 250
    End Type'  存放Winsock版本等信息的结构
    Private Type WSADATA
        wVersion As Integer
        wHighVersion As Integer
        szDescription(0 To MAX_WSADescription) As Byte
        szSystemStatus(0 To MAX_WSASYSStatus) As Byte
        wMaxSockets As Long
        wMaxUDPDG As Long
        dwVendorInfo As Long
    End TypeDim ICMPOPT As ICMP_OPTIONS'  返回状态信息
    Private Function GetStatusCode(status As Long) As String
       Dim msg As String
       Select Case status
          Case IP_SUCCESS:               msg = "ip success"
          Case IP_BUF_TOO_SMALL:         msg = "ip buf too_small"
          Case IP_DEST_NET_UNREACHABLE:  msg = "ip dest net unreachable"
          Case IP_DEST_HOST_UNREACHABLE: msg = "ip dest host unreachable"
          Case IP_DEST_PROT_UNREACHABLE: msg = "ip dest prot unreachable"
          Case IP_DEST_PORT_UNREACHABLE: msg = "ip dest port unreachable"
          Case IP_NO_RESOURCES:          msg = "ip no resources"
          Case IP_BAD_OPTION:            msg = "ip bad option"
          Case IP_HW_ERROR:              msg = "ip hw_error"
          Case IP_PACKET_TOO_BIG:        msg = "ip packet too_big"
          Case IP_REQ_TIMED_OUT:         msg = "ip req timed out"
          Case IP_BAD_REQ:               msg = "ip bad req"
          Case IP_BAD_ROUTE:             msg = "ip bad route"
          Case IP_TTL_EXPIRED_TRANSIT:   msg = "ip ttl expired transit"
          Case IP_TTL_EXPIRED_REASSEM:   msg = "ip ttl expired reassem"
          Case IP_PARAM_PROBLEM:         msg = "ip param_problem"
          Case IP_SOURCE_QUENCH:         msg = "ip source quench"
          Case IP_OPTION_TOO_BIG:        msg = "ip option too_big"
          Case IP_BAD_DESTINATION:       msg = "ip bad destination"
          Case IP_ADDR_DELETED:          msg = "ip addr deleted"
          Case IP_SPEC_MTU_CHANGE:       msg = "ip spec mtu change"
          Case IP_MTU_CHANGE:            msg = "ip mtu_change"
          Case IP_UNLOAD:                msg = "ip unload"
          Case IP_ADDR_ADDED:            msg = "ip addr added"
          Case IP_GENERAL_FAILURE:       msg = "ip general failure"
          Case IP_PENDING:               msg = "ip pending"
          Case PING_TIMEOUT:             msg = "ping timeout"
          Case Else:                     msg = "unknown  msg returned"
       End Select
       GetStatusCode = CStr(status) & "   [ " & msg & " ]"
    End Function
      

  2.   

    '  获得一个整数的高字节位
    Private Function HiByte(ByVal wParam As Long) As Integer
        HiByte = wParam \ &H100 And &HFF&
    End Function'  获得一个整数的低字节位
    Private Function LoByte(ByVal wParam As Long) As Integer
        LoByte = wParam And &HFF&
    End Function'  Ping一个IP地址
    Private Function Ping(szAddress As String, ECHO As ICMP_ECHO_REPLY) As Long
        Dim hPort As Long
        Dim dwAddress As Long
        Dim sDataToSend As String
        Dim iOpt As Long
        sDataToSend = "Echo This"
        dwAddress = AddressStringToLong(szAddress)
        hPort = IcmpCreateFile()
        If IcmpSendEcho(hPort, dwAddress, sDataToSend, Len(sDataToSend), 0, ECHO, Len(ECHO), PING_TIMEOUT) Then
            '如果ping成功,状态返回0。
             Ping = ECHO.RoundTripTime
        Else
            Ping = ECHO.status * -1
        End If
        Call IcmpCloseHandle(hPort)
    End Function
     
    '  将文本框中的IP地址转换成系统识别的长整数形式
    Function AddressStringToLong(ByVal tmp As String) As Long
        Dim i As Integer
        Dim parts(1 To 4) As String
        i = 0
        '转换IP地址
        While InStr(tmp, ".") > 0
            i = i + 1
            parts(i) = Mid(tmp, 1, InStr(tmp, ".") - 1)
            tmp = Mid(tmp, InStr(tmp, ".") + 1)
        Wend
        i = i + 1
        parts(i) = tmp
        If i <> 4 Then
            AddressStringToLong = 0
            Exit Function
        End If
        AddressStringToLong = Val("&H" & Right("00" & Hex(parts(4)), 2) & Right("00" & Hex(parts(3)), 2) & Right("00" & Hex(parts(2)), 2) & Right("00" & Hex(parts(1)), 2))
    End Function'  初始化Socket
    Private Function SocketsInitialize() As Boolean
        Dim WSAD As WSADATA
        Dim X As Integer
        Dim szLoByte As String
        Dim szHiByte As String
        Dim szBuf As String
        
        '初始化Socket
        X = WSAStartup(WS_VERSION_REQD, WSAD)
        If X <> 0 Then
            MsgBox "Windows Sockets for 32 bit Windows " & "environments is not successfully responding."
            Exit Function
        End If
        
         '  判断是否有支持足够的Socket
        If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or (LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then
            szHiByte = Trim$(Str$(HiByte(WSAD.wVersion)))
            szLoByte = Trim$(Str$(LoByte(WSAD.wVersion)))
            szBuf = "Windows Sockets Version " & szLoByte & "." & szHiByte
            szBuf = szBuf & " is not supported by Windows " & "Sockets for 32 bit Windows environments."
            MsgBox szBuf, vbExclamation
            Exit Function
        End If
        
        '  判断Winsock的版本是否被32为Winsock支持
        If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then
            szBuf = "This application requires a minimum of " & Trim$(Str$(MIN_SOCKETS_REQD)) & " supported sockets."
            MsgBox szBuf, vbExclamation
            Exit Function
        End If
        SocketsInitialize = True
    End Function'  关闭Sockets
    Private Sub SocketsCleanup()
        Dim X As Long
        '关闭Sockets
        X = WSACleanup()
        If X <> 0 Then
            MsgBox "Windows Sockets error " & Trim$(Str$(X)) & " occurred in Cleanup.", vbExclamation
        End If
    End SubPrivate Sub Command1_Click()
        Dim ECHO As ICMP_ECHO_REPLY
        Dim pos As Integer
        If SocketsInitialize() Then
            'ping地址
            Call Ping(Text2.Text, ECHO)
            '显示ping结果
            Text1(0).Text = GetStatusCode(ECHO.status)
            Text1(1).Text = ECHO.RoundTripTime & " ms"
            Text1(2).Text = ECHO.DataSize & " bytes"
            If Left$(ECHO.Data, 1) <> Chr$(0) Then
                pos = InStr(ECHO.Data, Chr$(0))
                Text1(3).Text = Left$(ECHO.Data, pos - 1)
            End If
            Text1(4).Text = ECHO.DataPointer
            SocketsCleanup
        End If
    End Sub