2011-11-17 68 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

感謝您的有用答案。我們決定通過套接字連接傳遞所需的信息。感謝你的幫助! –