Option ExplicitPrivate Declare Function gethostname Lib "WSOCK32.DLL" (ByVal szHost As String, ByVal dwHostLen As Long) As Long Private Declare Function gethostbyname Lib "WSOCK32.DLL" (ByVal szHost As String) As Long Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired As Long, lpWSADATA As WSADATA) As Long Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)' Socket错误常数和版本常数 Private Const SOCKET_ERROR As Long = -1 Private Const MAX_WSADescription = 256 Private Const MAX_WSASYSStatus = 128 Private Const ERROR_SUCCESS As Long = 0 Private Const WS_VERSION_REQD As Long = &H101 Private Const MIN_SOCKETS_REQD As Long = 1 Private Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD \ &H100 And &HFF& Private Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&' 存放主机信息的结构 Private Type HOSTENT hName As Long ' 主机的正式名称 hAliases As Long ' 主机别名列表 hAddrType As Integer ' 主机地址类型 hLen As Integer ' 主机地址长度 hAddrList As Long ' 主机IP地址列表 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 Integer wMaxUDPDG As Integer dwVendorInfo As Long End Type' 返回给定机器名的Ip地址,机器名为空时返回本机Ip地址 Private Function GetIPAddress(Optional sHost As String) As String Dim sHostName As String * 256 Dim lpHost As Long Dim HOST As HOSTENT Dim dwIPAddr As Long Dim tmpIPAddr() As Byte Dim i As Integer Dim sIPAddr As String Dim werr As Long
' 如果无法初始化Socket则退出函数 If Not SocketsInitialize() Then GetIPAddress = "" Exit Function End If
' 如果未指定主机名称,则取得本地主机名称并获取其IP If sHost = "" Then If gethostname(sHostName, 256) = SOCKET_ERROR Then werr = WSAGetLastError() GetIPAddress = "" SocketsCleanup Exit Function End If sHostName = Trim$(sHostName) Else sHostName = Trim$(sHost) & Chr$(0) End If
' 获得指向主机信息结构的指针 lpHost = gethostbyname(sHostName) ' 如果指针为零,则错误退出 If lpHost = 0 Then werr = WSAGetLastError() GetIPAddress = "" SocketsCleanup Exit Function End If
' 获得最终的主机IP地址字符串 For i = 1 To HOST.hLen sIPAddr = sIPAddr & tmpIPAddr(i) & "." Next ' 返回 GetIPAddress = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)
' 释放Socket库所占用的系统资源 SocketsCleanup End Function' 初始化Socket Private Function SocketsInitialize(Optional sErr As String) As Boolean Dim WSAD As WSADATA Dim sLoByte As String Dim sHiByte As String
' 初始化Winsock DLL,并判断版本是否满足要求 If WSAStartup(WS_VERSION_REQD, WSAD) <> ERROR_SUCCESS Then sErr = "The 32-bit Windows Socket is not responding." SocketsInitialize = False Exit Function End If
' 判断是否有支持足够的Socket If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then sErr = "This application requires a minimum of " & _ CStr(MIN_SOCKETS_REQD) & " supported sockets." SocketsInitialize = False Exit Function End If
' 判断Winsock的版本是否被32为Winsock支持 If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or _ (LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And _ HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then sHiByte = CStr(HiByte(WSAD.wVersion)) sLoByte = CStr(LoByte(WSAD.wVersion)) sErr = "Sockets version " & sLoByte & "." & sHiByte & _ " is not supported by 32-bit Windows Sockets." SocketsInitialize = False Exit Function End If
SocketsInitialize = True End Function' 释放Socket库所占用的系统资源 Private Sub SocketsCleanup() If WSACleanup() <> ERROR_SUCCESS Then App.LogEvent "Socket error occurred in Cleanup.", vbLogEventTypeError End If End Sub' 获得一个整数的高字节位 Private Function HiByte(ByVal wParam As Integer) HiByte = wParam \ &H1 And &HFF& End Function' 获得一个整数的低字节位 Private Function LoByte(ByVal wParam As Integer) LoByte = wParam And &HFF& End FunctionPrivate Sub Command1_Click() On Error Resume Next Screen.MousePointer = vbHourglass TxtIp.Text = GetIPAddress(TxtCmpName.Text) Screen.MousePointer = vbDefault End Sub
Private Declare Function gethostbyname Lib "WSOCK32.DLL" (ByVal szHost As String) As Long
Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired As Long, lpWSADATA As WSADATA) As Long
Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long
Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)' Socket错误常数和版本常数
Private Const SOCKET_ERROR As Long = -1
Private Const MAX_WSADescription = 256
Private Const MAX_WSASYSStatus = 128
Private Const ERROR_SUCCESS As Long = 0
Private Const WS_VERSION_REQD As Long = &H101
Private Const MIN_SOCKETS_REQD As Long = 1
Private Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD \ &H100 And &HFF&
Private Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&' 存放主机信息的结构
Private Type HOSTENT
hName As Long ' 主机的正式名称
hAliases As Long ' 主机别名列表
hAddrType As Integer ' 主机地址类型
hLen As Integer ' 主机地址长度
hAddrList As Long ' 主机IP地址列表
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 Integer
wMaxUDPDG As Integer
dwVendorInfo As Long
End Type' 返回给定机器名的Ip地址,机器名为空时返回本机Ip地址
Private Function GetIPAddress(Optional sHost As String) As String
Dim sHostName As String * 256
Dim lpHost As Long
Dim HOST As HOSTENT
Dim dwIPAddr As Long
Dim tmpIPAddr() As Byte
Dim i As Integer
Dim sIPAddr As String
Dim werr As Long
' 如果无法初始化Socket则退出函数
If Not SocketsInitialize() Then
GetIPAddress = ""
Exit Function
End If
' 如果未指定主机名称,则取得本地主机名称并获取其IP
If sHost = "" Then
If gethostname(sHostName, 256) = SOCKET_ERROR Then
werr = WSAGetLastError()
GetIPAddress = ""
SocketsCleanup
Exit Function
End If sHostName = Trim$(sHostName)
Else
sHostName = Trim$(sHost) & Chr$(0)
End If
' 获得指向主机信息结构的指针
lpHost = gethostbyname(sHostName) ' 如果指针为零,则错误退出
If lpHost = 0 Then
werr = WSAGetLastError()
GetIPAddress = ""
SocketsCleanup
Exit Function
End If
' 从指定内存取得数据
CopyMemory HOST, lpHost, Len(HOST)
CopyMemory dwIPAddr, HOST.hAddrList, 4
' 重新动态分配变量内存
ReDim tmpIPAddr(1 To HOST.hLen)
' 将主机地址存储到tmpIPAddr中
CopyMemory tmpIPAddr(1), dwIPAddr, HOST.hLen
' 获得最终的主机IP地址字符串
For i = 1 To HOST.hLen
sIPAddr = sIPAddr & tmpIPAddr(i) & "."
Next ' 返回
GetIPAddress = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)
' 释放Socket库所占用的系统资源
SocketsCleanup
End Function' 初始化Socket
Private Function SocketsInitialize(Optional sErr As String) As Boolean
Dim WSAD As WSADATA
Dim sLoByte As String
Dim sHiByte As String
' 初始化Winsock DLL,并判断版本是否满足要求
If WSAStartup(WS_VERSION_REQD, WSAD) <> ERROR_SUCCESS Then
sErr = "The 32-bit Windows Socket is not responding."
SocketsInitialize = False
Exit Function
End If
' 判断是否有支持足够的Socket
If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then
sErr = "This application requires a minimum of " & _
CStr(MIN_SOCKETS_REQD) & " supported sockets."
SocketsInitialize = False
Exit Function
End If
' 判断Winsock的版本是否被32为Winsock支持
If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or _
(LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And _
HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then sHiByte = CStr(HiByte(WSAD.wVersion))
sLoByte = CStr(LoByte(WSAD.wVersion)) sErr = "Sockets version " & sLoByte & "." & sHiByte & _
" is not supported by 32-bit Windows Sockets." SocketsInitialize = False
Exit Function
End If
SocketsInitialize = True
End Function' 释放Socket库所占用的系统资源
Private Sub SocketsCleanup()
If WSACleanup() <> ERROR_SUCCESS Then
App.LogEvent "Socket error occurred in Cleanup.", vbLogEventTypeError
End If
End Sub' 获得一个整数的高字节位
Private Function HiByte(ByVal wParam As Integer)
HiByte = wParam \ &H1 And &HFF&
End Function' 获得一个整数的低字节位
Private Function LoByte(ByVal wParam As Integer)
LoByte = wParam And &HFF&
End FunctionPrivate Sub Command1_Click()
On Error Resume Next
Screen.MousePointer = vbHourglass
TxtIp.Text = GetIPAddress(TxtCmpName.Text)
Screen.MousePointer = vbDefault
End Sub