jwcolby
jwcolby at colbyconsulting.com
Tue Jun 30 06:59:11 CDT 2009
ROTFL. Me? SALES? Bite your tongue you scalliwag. John W. Colby www.ColbyConsulting.com Gustav Brock wrote: > Hi John (and Max) > > If you download the code, a whole module is for resolving IP address and hostname. Nothing rocket science but refined for the purpose. > It even features a static collection inspired by your sales talk on collections. > > The key function is this: > > <code> > Private Function GetIPFromHostName( _ > ByVal strHostname As String) _ > As String > > ' Converts a host name to its IP address. > ' > ' If strHostname > ' - is zero length, local IP address is returned. > ' - is "localhost", IP address 127.0.0.1 is returned. > ' - cannot be resolved, unknown IP address 0.0.0.0 is returned. > > Const clngAddressNone As Long = 0 > ' The Address is offset 12 bytes from the > ' start of the HOSENT structure. > Const clngAddressOffset As Long = 12 > ' Size of address part. > Const clngAddressChunk As Long = 4 > ' Address to return if none found. > Const cstrAddressZero As String = "0.0.0.0" > > ' Address of HOSENT structure. > Dim ptrHosent As Long > ' Address of name pointer. > Dim ptrName As Long > ' Address of address pointer. > Dim ptrAddress As Long > Dim ptrIPAddress As Long > Dim ptrIPAddress2 As Long > Dim stzHostName As String > Dim strAddress As String > > stzHostName = strHostname & vbNullChar > ptrHosent = GetHostByName(stzHostName) > > If ptrHosent = clngAddressNone Then > ' Return address zero. > strAddress = cstrAddressZero > Else > ' Assign pointer addresses and offset Null-terminated list > ' of addresses for the host. > ' Note: > ' We are retrieving only the first address returned. > ' To return more than one, define strAddress as a string array > ' and loop through the 4-byte ptrIPAddress members returned. > ' The last item is a terminating null. > ' All addresses are returned in network byte order. > ptrAddress = ptrHosent + clngAddressOffset > > ' Get the IP address. > CopyMemory ptrAddress, ByVal ptrAddress, clngAddressChunk > CopyMemory ptrIPAddress, ByVal ptrAddress, clngAddressChunk > CopyMemory ptrIPAddress2, ByVal ptrIPAddress, clngAddressChunk > > strAddress = GetInetStrFromPtr(ptrIPAddress2) > End If > > GetIPFromHostName = strAddress > > End Function > </code> > > Problem is that you may have more than one adapter. As stated, this function lists only one which typically is the NIC for your LAN. > Another function reads this out: > > <code> > Public Function MachineHostAddress( _ > Optional ByVal strHostname As String) _ > As String > > ' Retrieves IP address of the machine with the host name > ' strHostname. > ' If a zero length host name or no host name is passed, the > ' address of this machine is returned. > ' If host name localhost is passed, 127.0.0.1 is returned. > ' If the host name cannot be resolved, 0.0.0.0 is returned. > ' > ' The host addresses are preserved in a static collection to > ' reduce look up time for repeated calls. > > ' If strHostname is an empty string, the local host address > ' will be looked up. > ' However, an empty string cannot be a key in a collection. > ' Use this key to store the local host address. > Const cstrKeyThisHost As String = " " > > Static colAddress As New Collection > > Dim strIpAddress As String > > ' Ignore error when looking up a key in collection > ' colAddress that does not exist. > On Error Resume Next > > If Len(strHostname) = 0 Then > strHostname = cstrKeyThisHost > End If > strIpAddress = colAddress.Item(strHostname) > ' If strHostname is not found, an error is raised. > If Err.Number <> 0 Then > ' This host name has not been looked up previously. > If WinSocketsStart() = True Then > ' Obtain the host address. > ' Trim strHostname to pass a zero length string when > ' looking up the address of the local host. > strIpAddress = GetIPFromHostName(Trim(strHostname)) > ' Store the host address. > colAddress.Add strIpAddress, strHostname > > Call WinSocketsClean > End If > End If > > MachineHostAddress = strIpAddress > > End Function > </code> > > For the helper functions, download the full code. > > However, no function is included to reveal the subnet mask. The only "human" method I can locate for this purpose is to look up the registry: > > HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces > > Browse these for the key DhcpIPAddress - or, if this is not found, IPAddress - to locate the interface that matches the IP address you retrieved. > When matched, look up the key DhcpSubnetMask - or SubnetMask - to obtain the current subnet mask. > > Armed with this - your IP address and subnet mask - you can easily calculate the list of possible IP address on the current LAN. > > /gustav > > >>>> Gustav at cactus.dk 29-06-2009 20:34 >>> > Hi John > > As explained in the article on how to create a kind of confirmation system, you could set up a simple two-way system with a single syslog app broadcasting at low frequency "Here I am, and if you are an app from JC, record my address and report back". Your app, when running at the user, would pick up that message and send back a message for the syslog app to collect the addresses of currently running application copies. When a user signs off, after a time-out the syslog app realizes that this copy is off and removes it from the list. Thus, a current list of active applications can be maintained and they can communicate for whatever reason you decide. > > Note that communication between machines can really be done in many ways, it is just that syslog is an established standard for simple text messages of about 1K, and if that fits, why reinvent the wheel? > > /gustav > > >>>> jwcolby at colbyconsulting.com 29-06-2009 20:05 >>> > Gustav, > > As I mentioned, I have been looking for something like this for years, however everyone has to have > a list of IPs that can be used with it to make it useful. > > I suppose I could kind of bootstrap this thing. The server address could be found by manual > observation, then logged in a table along with the machine name. Each application FE instance looks > and sends a message that it is logged in. The RECEIVER grabs the IP address and looks it up in the > table. If not there it stores the IP in the table. Of course then the machine name has to be > included in the message. > > I suppose that I could develop a message library, such that every time an application it fires a > LOGIN message to everyone already in the table. The login message has a machine name as the data > and apparently this widget automatically gets the IP address. My clients rarely have more than 25 > or so workstations running the application so this shouldn't cause too much grief. Thus anyone > listening logs the new person's data into the table if it isn't already there. > > Kind of crude but that allows any single running application (that you can manually get the IP for) > to bootstrap the system and build the list of IPs and machine names. > > John W. Colby > www.ColbyConsulting.com > > > _______________________________________________ > dba-VB mailing list > dba-VB at databaseadvisors.com > http://databaseadvisors.com/mailman/listinfo/dba-vb > http://www.databaseadvisors.com > >