Registreren   Inloggen   Zoeken:  Nu zoeken
zondag 11 mei 2008
     
SDN Magazine #95 | november 2007

Visual Basic in een Connected World 

We leven in een wereld waarbij het overgrote gedeelte van alle computers verbonden is met een bedrijfsnetwerk of het Internet. Onze gebruikers delen documenten, downloaden muziek en uploaden foto’s. Naast Internet, is bij bedrijven ook het gebruik van het lokale netwerk niet meer weg te denken. Zelfs bij thuisgebruikers is een lokaal netwerk geen uitzondering meer. Het kan niet anders dat al deze ontwikkelingen van invloed zijn op de manier waarop wij software moeten bouwen. Er wordt van onze software ook verwacht dat het op een vriendelijke manier om kan gaan met deze technieken. Het .NET Framework biedt, in combinatie met Visual Basic 2005, een aantal klassen waarmee netwerkgerelateerde programmeerproblemen kunnen worden opgelost. De meeste van deze specifieke klassen komen allemaal uit de namespace System.Net. In dit artikel laat ik een aantal voorbeelden zien hoe je Visual Basic 2005 kunt inzetten om de connectiviteit van je applicaties te verbeteren.

Beschikbaarheid van het netwerk
Wat je ook gaat doen, een gedeelde map benaderen op een server of het downloaden van een bestand van het Internet, er moet een netwerkverbinding zijn. Het bepalen of een computer verbonden is met een netwerkinterface is kinderlijk eenvoudig. Het .NET Framework 2.0 en hoger kent de namespace System.Net.NetworkInformation waarin een groot aantal klassen en methoden verborgen liggen. Een ervan is de methode GetIsNetworkAvailable.

Imports System.Net.NetworkInformation.NetworkInterface

Public Function IsNetwerkBeschikbaar() As Boolean

  ' Bepaal of het netwerk beschikbaar is
  Return GetIsNetworkAvailable()

End Function
Listing 1

Zoals je in Listing 2 kunt zien, ligt het gebruik van deze functie voor de hand.

' Dimensioneer en instantieer variabelen
Dim blnNetwerkBeschikbaar As Boolean = IsNetwerkBeschikbaar()
Dim strWelNiet As String = ""

' Bepaal de tekst 'wel' of 'niet'
If blnNetwerkBeschikbaar = True Then
  strWelNiet = "wel"
Else
  strWelNiet = "niet"
End If

' Toon resultaat
MessageBox.Show("Het netwerk is " & strWelNiet & " beschikbaar.")

Listing 2

De klasse NetworkInterface kent naast de hierboven besproken methode GetIsNetworkAvailable ook de methode GetAllNetworkInterfaces. Deze methode retourneert een array van objecten van het type NetWorkInterface. Hiermee bepaal je dus een lijst met netwerkadapters op het systeem. Dit kan een normale netwerkkaart zijn, een draadloze netwerkadapter maar bijvoorbeeld ook een VPN verbinding naar kantoor of een klant. Vervolgens kun je de klasse IPInterfaceProperties gebruiken om informatie over ondermeer de DNS te verkrijgen. In Listing 3 zie je dat je ook gegevens over de gebruikte IP – en MAC adressen kunt bepalen. Aangezien het MAC adres van je netwerkkaart als redelijk uniek kan worden beschouwd, kun je dat gegeven prima toepassen bij extra beveiligingen binnen je software. Het is niet ingewikkeld om, analoog aan het instellen van bijvoorbeeld een draadloos netwerk, je software alleen open te stellen voor systemen waarvan het MAC adres geregistreerd staat in de eigen database.

Imports System.Net.NetworkInformation
Imports System.Net.NetworkInformation.NetworkInterface

Dim objAdapters As NetworkInterface()
Dim objIPProperties As IPInterfaceProperties

' Vul array met alle netwerkadapters
objAdapters = NetworkInterface.GetAllNetworkInterfaces

' Doorloop alle adapters
For Each objAdapter As NetworkInterface In objAdapters
  ' Bepaal per adapter de IP eigenschappen
  objIPProperties = objAdapter.GetIPProperties

  With objAdapter
    Console.WriteLine(.Name)
    Console.WriteLine("(" & .Description & ")")
    Console.WriteLine("    Snelheid       : " & _
                (.Speed / 1000000).ToString & " Mbps")
    Console.WriteLine("    Status         : " & _
                      .OperationalStatus.ToString)
    Console.WriteLine("    Dynamische DNS : " & _
                  objIPProperties.IsDynamicDnsEnabled)
    If objIPProperties.DnsAddresses.Count > 0 Then
      Console.WriteLine("    IP adres DNS   : " & _
             objIPProperties.DnsAddresses(0).ToString)
    End If
    Console.WriteLine("    MAC adres      : " & _
                       .GetPhysicalAddress().ToString)
  End With
Next

Listing 3

De code in listing 3 geeft op mijn systeem het resultaat dat is weergegeven in Listing 4.

Jansen Beheer B.V. - VPN verbinding
(Jansen Beheer B.V. - VPN verbinding)
    Snelheid       : 54 Mbps
    Status         : Up
    Dynamische DNS : False
    IP adres DNS   : 192.168.25.200
    MAC adres      :
Bluetooth-netwerkverbinding 3
(Bluetooth-apparaat (Personal Area Network) #3)
    Snelheid       : 1 Mbps
    Status         : Down
    Dynamische DNS : True
    IP adres DNS   : fec0:0:0:ffff::1%1
    MAC adres      : 00125B5932C5
LAN-verbinding 2
(Bluetooth Personal Area Network)
    Snelheid       : 3 Mbps
    Status         : Down
    Dynamische DNS : True
    IP adres DNS   : fec0:0:0:ffff::1%1
    MAC adres      : 0919C18CABE8
LAN-verbinding
(Marvell Yukon 88E8036 PCI-E Fast Ethernet Controller)
    Snelheid       : 100 Mbps
    Status         : Down
    Dynamische DNS : True
    IP adres DNS   : 10.0.0.138
    MAC adres      : 0013D9B552DB
Draadloze netwerkverbinding
(Intel(R) PRO/Wireless 3945ABG Network Connection)
    Snelheid       : 54 Mbps
    Status         : Up
    Dynamische DNS : True
    IP adres DNS   : 10.0.0.138
    MAC adres      : 0819B27EB656

Listing 4

Met de code uit Listing 3 kun je bijvoorbeeld tijdens het starten van je applicatie testen of het netwerk beschikbaar is. Afhankelijk van die beschikbaarheid kun je eventueel de functionaliteit van je software beperken of data opslaan in een local data cache. Indien je Microsoft Outlook offline gebruikt, dan kun je wel een mailtje maken en op verzenden klikken, maar het uitgaande bericht wordt vervolgens in je Postvak UIT geplaatst. Microsoft Outlook is het schoolvoorbeeld van een applicatie waar op heel intelligente manier wordt omgegaan met zowel connected als disconnected situaties. Maar wat doe jij wanneer er tijdens het werken met je applicatie de netwerkverbinding wegvalt? Of andersom? Je applicatie wordt offline gestart, maar na verloop van tijd is de netwerkverbinding hersteld. Onderneem je dan actie? Het zou erg prettig zijn dat je dan binnen je applicatie een event kunt afvangen, om adequaat met die situatie om te gaan. Hoewel een beetje verstopt, biedt Visual Basic 2005 je de middelen om inderdaad zo’n event af te vangen. Een Visual Basic Windows applicatie kent namelijk het My.Application.NetworkAvailabilityChanged event. Het treedt op wanneer de netwerkverbinding wordt verbroken of juist verbonden. De huidige status kun je vervolgens bepalen door de eigenschap e.IsNetworkAvailable uit te lezen. Zie Listing 5.

Private Sub MyApplication_NetworkAvailabilityChanged _
   (ByVal sender As Object, ByVal e As _
   Devices.NetworkAvailableEventArgs) _
         Handles Me.NetworkAvailabilityChanged

  Dim blnNetwerkBeschikbaar As Boolean = e.IsNetworkAvailable
  Dim strWelNiet As String = ""

  ' Bepaal de tekst 'wel' of 'niet'
  If blnNetwerkBeschikbaar = True Then
    strWelNiet = "wel"
  Else
    strWelNiet = "niet"
  End If

  ' Toon resultaat
  MessageBox.Show("Het netwerk is " & strWelNiet & " beschikbaar.")

End Sub
Listing 5

Zoals reeds gezegd moet code uit Listing 5 geplaatst worden op een, op het eerste gezicht, niet zo voor de hand liggende plaats. Dit event, naast enkele andere zoals Startup en Shutdown, kun je namelijk vinden in het bestand ApplicationEvents.vb. Als je de bestandsnaam van dit bestand ziet, dan is de locatie van deze code opeens een stuk logischer. Dit bestand is echter standaard verborgen en je moet het dus eerst zichtbaar maken. Je onderneemt hiervoor de volgende stappen:
• Selecteer het project in de Solutions Explorer;
• Selecteer vervolgens Properties uit het menu Project;
• Selecteer het tabblad Applications en klik op de knop View Application Events;
• Het codevenster van de klasse MyApplication wordt geopend.
 

SDN Magazine #95 - Figuur 1 
Figuur 1
Events binnen de klasse MyApplication.

Enkele opmerkingen bij het gebruik van deze klasse. Op systemen met Windows 95 en Windows 98 treedt het event niet op. Dit geldt ook voor Windows 2000 systemen die draaien onder een niet-administrator account. Indien je oudere systemen moet ondersteunen moet je iets anders verzinnen. Je zou natuurlijk zelf periodiek de eerder beschreven eigen methode IsNetwerkBeschikbaar kunnen aanroepen en op basis van het resultaat de desbetreffende actie ondernemen. Daarentegen is het een prettige bijkomstigheid dat dit event optreedt in dezelfde thread als de gebruikersinterface. Hierdoor kun je vanuit dit event ook de gebruikersinterface aanpassen om bijvoorbeeld in de statusbalk van je applicatie een ander pictogram te tonen. Om code uit Listing 5 te testen kun je, nadat de applicatie is gestart eenvoudigweg de netwerkkabel uit je computer verwijderen of juist terugplaatsen. In mijn geval heb ik even mijn draadloze netwerkkaart uit- en aangezet.

IP-adressen en host names
Elke computer binnen een netwerk en dus ook op het Internet, heeft een IP-adres. Dit adres is nodig om de machine binnen een netwerk te kunnen identificeren. IP-adressen worden op de meeste systemen genoteerd als vier getallen, elk gescheiden door een punt. Ook elke webserver heeft een IP-adres. Omdat zo’n IP-adres lastig te onthouden zijn zogenaamde hostnames bedacht. Zo’n hostname is feitelijk niets anders dan een vriendelijke naam voor een ingewikkeld nummer. Zo is ‘www.obelink.com’ een host name voor het IP adres 212.79.242.162. Voor het bepalen van de host name van de huidige machine heb je minimale code nodig. Zie Listing 6 en figuur 2.

Public Function BepaalHostName() As String

    ' Bepaal de naam van deze computer
    Return System.Net.Dns.GetHostName()

End Function

  ....
  ....

  MessageBox.Show(BepaalHostName, "Host Name")
Listing 6
 
SDN Magazine #95 | Figuur 2 
Figuur 2
Bepaal de naam van de computer.

Hoewel het bepalen van het huidige IP-adres, of in sommige gevallen de IP-adressen, niet veel ingewikkelder is, kost het wel iets meer code dan alleen de host naam bepalen. Het is namelijk mogelijk dat de huidige computer niet één, maar meerdere IP-adressen heeft. Naast een normale netwerkkaart, kan bijvoorbeeld ook een draadloze netwerkkaart verbonden zijn.  Tevens krijg je ook een IP-adres toegewezen wanneer je een VPN verbinding opzet naar een extern netwerk. Hierdoor is het zelfs mogelijk dat om gelijktijdig drie of meer IP-adressen te hebben. Zie Listing 7.

Imports System.Net

Dim strBoodschap As String = ""
Dim strComputerNaam As String = ""
Dim objIPAdressen() As IPAddress = Nothing

' Bepaal de computernaam
strComputerNaam = BepaalHostName()

' Bepaal de IP-adressen voor deze computernaam
objIPAdressen = Dns.GetHostAddresses(strComputerNaam)

' Toon eerst de host name
strBoodschap = strComputerNaam & Environment.NewLine
' Doorloop alle IP-adressen.
For Each objIPAdres As IPAddress In objIPAdressen
    strBoodschap += "    " & objIPAdres.ToString & _
                    Environment.NewLine
Next

' Toon alle IP-adressen
MessageBox.Show(strBoodschap, "IP-adressen")

Listing 7

De methode System.Net.Dns.GetHostAddresses retourneert de in gebruik zijnde IP-adressen op de opgegeven host naam. In code uit Listing 7 maken we daarom dankbaar gebruik van de door ons eerder gemaakt functie BepaalHostName. Het kan zijn dat, wanneer je deze code draait op bijvoorbeeld een Windows Vista systeem, je verbaasd bent over het getoond formaat van het IP-adres. Windows Vista maakt gebruik van IPv6 en het standaard formaat van een IP-adres is hexadecimaal. Dit in tegenstelling tot een Windows XP machine. Deze zal standaard namelijk gebruik maken van IPv4.  Wanneer je deze adressen wilt converteren naar een meer vriendelijker formaat, dan kun je met de eigenschap AddressFamily op het object objIPAdres bepalen welke versie er in gebruik is. Op basis van die informatie kun je besluiten het adres te converteren naar een decimaal formaat.

 
SDN Magazine #95 | Figuur 3 
Figuur 3
Bepaal de IP-adressen op de huidige machine

We hebben nu gezien hoe we de host naam en het IP-adres van een computer kunnen bepalen. Bij het opzetten van een communicatieverbinding met een externe computer is het ook nodig om die informatie van een andere computer te bepalen. Hiervoor kun je gebruik maken van de methode System.Net.Dns.IPHostEntry.GetHostEntry. Op het object van het type IPHostEntry kun je vervolgens de eigenschappen HostName en AddressList aanroepen. Zie Listing 8.

Dim objIPHostEntry As IPHostEntry = Nothing

' Bepaal hostinformatie voor een IP-adres
objIPHostEntry = GetHostEntry("10.0.0.4")

MessageBox.Show(objIPHostEntry.HostName, _
               "Host name voor bepaal IP-adres")

Listing 8

Bovenstaande code retourneert de naam van de externe computer. In mijn geval de naam van de computer van mijn vrouw OBELINK_M. Wanneer het IP-adres door een gebruiker moet worden ingevoerd doe je er verstandig aan om eerst het IP-adres te valideren op en geldig formaat. Wanneer je namelijk een ongeldig formaat aanbiedt, dan weet je op voorhand dat de host naam niet gevonden kan worden. Het duurt vrij lang voordat functie hier achter komt. Het valideren van een IP-adres kun je overigens vrij eenvoudig doen met behulp van een regular expression. Zie Listing 9.

' MessageBox.Show(IsGeldigIPAdres("123.123.0.255")) 'True
' MessageBox.Show(IsGeldigIPAdres("256.1.0.255")) 'False

Function IsGeldigIPAdres(ByVal strIPAdres As String) As Boolean

  Return System.Text.RegularExpressions.Regex.IsMatch(strIPAdres, _
  "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$")

End Function
Listing 9

Voor het bepalen van het IP-adres op basis van een host naam, komt een groot deel van de eerder besproken technieken weer aan de orde. De truc zit hem in feit dat we nu een object aanmaken van het type IPHostEntry en vervolgens op dat object de eigenschap AdressList. Deze eigenschap retourneert een array van objecten van het type IPAddress. Hoe we met zo’n array kunnen omgaan is reeds uitgebreid aan bod gekomen. Zolang het bedrijf waar ik mijn websites host, geen server vervangt zal het resultaat van code uit Listing 10 moeten leiden tot een dialoogkader met de tekst: 212.79.242.162.

Dim strBoodschap As String = ""
Dim objIPHostEntry As IPHostEntry = Nothing
Dim objIPAdres As IPAddress = Nothing

' Bepaal hostinformatie voor Url of computernaam
objIPHostEntry = GetHostEntry("
www.obelink.com")

' Doorloop alle IP-adressen
For Each objIPAdres In objIPHostEntry.AddressList
    strBoodschap += objIPAdres.ToString & vbCrLf
Next

' Toon boodschap
MessageBox.Show(strBoodschap, "IP-adressen voor bepaalde host")

Listing 10

In dit artikel heb ik je laten kennismaken met een aantal basisprincipes van het ‘netwerk-programmeren’ met Visual Basic 2005. Het .NET Framework biedt je een groot aantal klassen waarmee dit soort programmeerproblemen vrij makkelijk zijn op te lossen. Wanneer je deze kennis in praktijk gaat toepassen, zul je echter ook gaan merken dat niet alles mogelijk is met native .NET klassen. Voor het maken van bijvoorbeeld een eenvoudige share moet je weer uitwijken naar het gebruik van API’s, zoals we dat met Visual Basic 6 ook moesten. Gelukkig zijn er op het Internet veel van die voorbeelden te vinden, waardoor je er feitelijk net zo snel mee aan de slag kan.

Advertenties
Bestanden bij dit artikel
Leer ook Visual Basic!

Visual Basic 2005 - de Basis | André Obelink

 


Microsoft Certified Solution Developer

Microsoft Certified Professional

Microsoft Most Valuable Professional

VP Speakers Bureau - INETA Europe

Brainbench Certified Master Visual Basic 6.0 Programmer

Gebruiksovereenkomst   Privacybeleid   Copyright 2005 André Obelink