2011-11-17 113 views
1

问题确定远程主机名VB6 winsock的 - GetHostByAddr相当于

我试图找出最可靠的方法来确定连接了在VB6使用Winsock连接计算机的工作站名称。

具体细节

一个服务器承载写在VB6一个窗口服务。同一网络上的其他计算机连接到此服务,并且该服务需要确定连接到该服务的计算机的计算机名称。

可能的代码

VB6的Winsock控件有,我可以用它来获取IP一个.RemoteHostIP属性。

我发现这个WINAPI代码使用IP来获取远程计算机的名称:

Private mbInitialized As Boolean 
    Const WSADescription_Len = 256 
    Const WSASYS_Status_Len = 128 
    Const AF_INET = 4& 


    Private Type HOSTENT 
     hName As Long 
     hAliases As Long 
     hAddrType As Integer 
     hLength As Integer 
     hAddrList As Long 
    End Type 


    Private Type WSADATA 
     wversion As Integer 
     wHighVersion As Integer 
     szDescription(0 To WSADescription_Len) As Byte 
     szSystemStatus(0 To WSASYS_Status_Len) As Byte 
     iMaxSockets As Integer 
     iMaxUdpDg As Integer 
     lpszVendorInfo As Long 
    End Type 

    Private Declare Function WSAStartup Lib "wsock32" (ByVal VersionReq As Long, WSADataReturn As WSADATA) As Long 
    Private Declare Function WSACleanup Lib "wsock32"() As Long 
    Private Declare Function WSAGetLastError Lib "wsock32"() As Long 
    Private Declare Function gethostbyaddr Lib "wsock32" (addr As Long, addrLen As Long, addrType As Long) As Long 
    Private Declare Function gethostbyname Lib "wsock32" (ByVal hostname As String) As Long 
    Private Declare Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long) 

    Private Sub Class_Initialize() 
     Dim wsa As WSADATA 
     mbInitialized = (WSAStartup(257, wsa) = 0) 
    End Sub 
    Private Sub Class_Terminate() 
     If mbInitialized Then 
     WSACleanup 
     End If 
    End Sub 

    'checks if string is valid IP address 

    Private Function CheckIP(IPToCheck As String) As Boolean 
     Dim TempValues 
     Dim iLoop As Long 
     Dim TempByte As Byte 
     On Error GoTo CheckIPError 

     TempValues = Split(IPToCheck, ".") 
     If UBound(TempValues) < 3 Then 
      Exit Function 
     End If 
     For iLoop = LBound(TempValues) To UBound(TempValues) 
      TempByte = TempValues(iLoop) 
     Next iLoop 

     CheckIP = True 

CheckIPError: 

    End Function 

    'converts IP address from string to sin_addr 

    Private Function MakeIP(strIP As String) As Long 

     Dim vTemp 
     Dim lngTemp As Long 
     Dim iLoop As Long 
     On Error GoTo MakeIPError 

     vTemp = Split(strIP, ".") 
     For iLoop = 0 To (UBound(vTemp) - 1) 
      lngTemp = lngTemp + (vTemp(iLoop) * (256^iLoop)) 
     Next iLoop 
     If vTemp(UBound(vTemp)) < 128 Then 
     lngTemp = lngTemp + (vTemp(UBound(vTemp)) * (256^3)) 

     Else 

      lngTemp = lngTemp + ((vTemp(UBound(vTemp)) - 256) * (256^3)) 
     End If 

     MakeIP = lngTemp 

MakeIPError: 
    End Function 

    'resolves IP address to host name 

    Private Function AddrToName(strAddr As String) As String 

     Dim heEntry As HOSTENT 
     Dim strHost As String * 255 
     Dim strTemp As String 
     Dim lngRet As Long 
     Dim lngIP As Long 

     On Error GoTo AddrToNameError 

     If CheckIP(strAddr) Then 
      lngIP = MakeIP(strAddr) 
      lngRet = gethostbyaddr(lngIP, 4, AF_INET) 
      If lngRet = 0 Then 
       Exit Function 
      End If 

      RtlMoveMemory heEntry, lngRet, Len(heEntry) 
      RtlMoveMemory ByVal strHost, heEntry.hName, 255 
      strTemp = TrimNull(strHost) 
      AddrToName = strTemp 

     End If 

AddrToNameError: 

    End Function 

    'resolves host name to IP address 

    Private Function NameToAddr(ByVal strHost As String) 

     Dim ip_list() As Byte 
     Dim heEntry As HOSTENT 
     Dim strIPAddr As String 
     Dim lp_HostEnt As Long 

     Dim lp_HostIP As Long 
     Dim iLoop As Integer 
     On Error GoTo NameToAddrError 

     lp_HostEnt = gethostbyname(strHost) 
     If lp_HostEnt = 0 Then 
      Exit Function 
     End If 

     RtlMoveMemory heEntry, lp_HostEnt, LenB(heEntry) 
     RtlMoveMemory lp_HostIP, heEntry.hAddrList, 4 
     ReDim ip_list(1 To heEntry.hLength) 

     RtlMoveMemory ip_list(1), lp_HostIP, heEntry.hLength 
     For iLoop = 1 To heEntry.hLength 
      strIPAddr = strIPAddr & ip_list(iLoop) & "." 
     Next 

     strIPAddr = Mid(strIPAddr, 1, Len(strIPAddr) - 1) 
     NameToAddr = strIPAddr 

NameToAddrError: 

    End Function 

    Public Function AddressToName(strIP As String) As String 

     If mbInitialized Then AddressToName = AddrToName(strIP) 

    End Function 

    Public Function NameToAddress(strName As String) As String 

     If mbInitialized Then NameToAddress = NameToAddr(strName) 

    End Function 

    Private Function TrimNull(sTrim As String) As String 

     Dim iFind As Long 

     iFind = InStr(1, sTrim, Chr(0)) 
     If iFind > 0 Then 
      TrimNull = Left(sTrim, iFind - 1) 
     Else 
      TrimNull = sTrim 
     End If 
    End Function 

可以称之为是这样的:

Dim obj As clsIPResolve 
Set obj = New clsIPResolve 

msgbox obj.AddressToName(frmMain.sckClient(i).RemoteHostIP) 
Set obj = Nothing 

问题:

  1. 有没有人知道这是否是在vb6中做到这一点的最好方法?我在我的测试环境中工作,但在“现实世界”中依赖它我有点紧张。

  2. 这是如何工作的?显然,使用远程机器的IP地址做某种反向DNS。它在哪里得到这些信息?路由器?别的地方?

感谢您提前提供任何帮助!

回答

0

1)该代码执行简单的DNS查找,因此根据定义将是网络名称。如果机器没有反向DNS名称,则不会得到任何有意义的名称,而应使用IP。
请注意,反向DNS名称与机器本身的工作站名称不同。为了得到这个,你需要成为域的一部分(我不能提供任何代码,但是WNet API应该获得这些信息,寻找NetBios名字),或者作为协议的一部分在套接字连接中传递它/初始握手。

2)它正在进行反向DNS查找,因此会查询您的本地名称服务器以尝试获取详细信息。然后,这将恢复并找到一个授权服务器,该服务器可以根据它的配置或域名上的机器名称给出答案。
如果这两台机器都在同一个(Windows)域中,它也会尝试在该地址上进行NetBios查找。

+0

感谢您的有用答案。我们决定通过套接字连接传递所需的信息。感谢你的帮助! –