确定远程主机名vb6 winsock - GetHostByAddr等价物

时间:2011-11-17 21:44:19

标签: sockets vb6 winsock

问题

我正在尝试找出最可靠的方法来确定通过vb6中的winsock连接连接的计算机的工作站名称。

具体细节信息

服务器托管用vb6编写的Windows服务。同一网络中的其他计算机连接到此服务,该服务需要确定连接到它的计算机的计算机名称。

可能的代码

vb6 winsock控件有一个.RemoteHostIP属性,可用于获取IP。

我发现这个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。它在哪里获取这些信息?路由器?在其他地方?

  3. 提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

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

2)它正在进行反向DNS查找,因此将查询您的本地名称服务器以尝试获取详细信息。然后,这将递归并找到一个授权服务器,该服务器可根据其配置方式或域中的计算机名称给出答案。
如果这些计算机都位于同一个(Windows)域中,它还会尝试对该地址执行NetBios查找。