Tutorial für Ping Class und Tracert

    • VB.NET

      Tutorial für Ping Class und Tracert

      Anleitung für einen Netzwerkping

      Dies soll ein kurzes Tutorial werden um EINE Möglichkeit zu zeigen, wie man mit allem drum und dran einen Ping via Vb.Net zu einer beliebigen IP-Adresse bzw Website schicken kann.
      Im 2. Schritt werde ich eine Klasse zeigen, wie man selber eine nicht im Framework 3.5 implementierte Tracert Klasse schreiben kann.
      Dies ist kein Tutorial über Sockets. Denn auch über die Socket-Class kann man ICMP Pakete senden und empfangen sondern für die Ping Class im System.Net.Networkinformation Namespace. Daher müssen wir auch als erstes folgendes Importieren:

      VB.NET-Quellcode

      1. Option Explicit On 'Klar
      2. Option Strict On 'Sollte immer an sein
      3. Imports System.Net
      4. Imports System.Net.NetworkInformation


      Für den Einstieg werden wir eine Formanwendung für eine einfache, sich wiederholende Ping Anfrage schreiben.
      Dazu benötigen wir eine Form mit diesem Aufbau:


      Also brauchen wir hier 3 Textboxen:
      txtRpt = Für das Intervall des Pings
      txtIP = Das wichtigste, die Eingabe für die IP/Website/Hostname
      txtTTL = Hier kommt die Time To Live rein

      Time To Live eines Pings gibt an, wie "weit" das Paket weitergereicht wird, bevor es "aufgibt" und zurückkommt (Mit Fehlermeldung, Ziel nicht erreichbar oder ähnlichem). Dies bekommt vor allem später für die Tracert Klasse Bedeutung. Daher ist es wichtig diesen Parameter zu verstehen


      2 Buttons (geht auch mit einem, aber wir nehmen 2)
      btnStart
      btnStop 'sollte soweit klar sein, start und stop den ping

      und eine Listview Namens ResultList mit 3 Spalten:

      IP, Status und ResponseTime

      Die Ausgabe/design ist natürlich variabel.


      Nun beginnen wir mit dem Code:

      VB.NET-Quellcode

      1. Public Class PingForm 'Name der Form
      2. Private WithEvents PingTimer As New Timer 'Wir benutzen für die Anfänger anfangsvariante einen Timer
      3. Private IpToPing As IPAddress 'unsere benötigte globale Variable die die IP Adresse enthalten wird
      4. 'Nun kommt das FormLoad Event, dort machen wir nicht viel:
      5. Private Sub PingForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      6. BtnStop.Enabled = False 'Wir deaktivieren den Stop Button
      7. TxtIP.Text = "www.google.de" 'wir setzen einen Default Wert für die IP/Hostname Textbox
      8. ResultList.View = View.Details 'wir setzen die Listview Ansicht auf Detail
      9. Me.AcceptButton = btnStart 'der Startbutton wird zum acceptButton der Form-> bei Druck auf enter wird dieser ausgelöst
      10. End Sub
      11. 'Nun kommen wir zum BtnStart.Click Event. Dieses ist entscheidend:
      12. Private Sub BtnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
      13. Dim Ip As IPAddress() 'Wir deklarieren ein leeres Array von IPAdressen
      14. ResultList.Items.Clear() 'Wir löschen alle Items der Listview
      15. Dim LItm As New ListViewItem 'Wir erstellen ein neues ListviewItem
      16. LItm.Text = TxtIP.Text 'Wir fügen noch einen Text hinzu
      17. 'Dieser ist erstmal das eingebene
      18. Try 'Fehler abfangen, falls der Hostname/die website nicht aufgelöst werden kann
      19. If Not IPAddress.TryParse(TxtIP.Text, IpToPing) Then 'Wir versuchen erstmal den Inhalt der Textbox
      20. 'in eine IPAdresse zu wandeln
      21. 'Dies ist natülich nur erfolgreich wenn wir eine IP eingeben,
      22. 'Andernfalls liefert TryParse False zurück und wir versuchen
      23. 'den Namen aufzulösen und in das leere IP Array zu schreiben:
      24. Ip = Dns.GetHostAddresses(TxtIP.Text) 'Die DNS Klasse aus dem Framework versucht dies
      25. 'schlägt dies Fehl, fliegen wir aus dem Try Block
      26. 'und kommen in den Catch Block und geben den Fehler aus
      27. 'Nun weisen wir unserer IP Variable die zurückgegebene erste IP Adresse aus unserem IP Array zu
      28. 'Da Webseiten auch mehr als eine IP haben können, gibt:
      29. 'Dns.GetHostAddresses ein array von IP's zurück, wir nehmen halt einfach die erste
      30. 'Da mindest eine aufgelöst werden MUSS
      31. IpToPing = Ip(0)
      32. End If
      33. PingTimer.Interval = Integer.Parse(txtRpt.Text) 'Nun geben wir dem Timer
      34. 'sein Intervall indem wir den Text der txtrpt in Integer umwandeln und zuweisen
      35. LItm.SubItems.Add("") 'und 2 Leeren Subitems
      36. LItm.SubItems.Add("")
      37. ResultList.Items.Add(LItm) 'Und fügen diesem der Listview zu
      38. 'Die Darstellung ist hier sicher nicht optimal.
      39. BtnStop.Enabled = True 'nun disablen wir den StartButton
      40. btnStart.Enabled = False 'und enablen den Stop Button
      41. PingTimer.Start() 'und starten den Timer
      42. Catch ex As Exception
      43. 'Gibts einen Fehler (Name nicht auflösbar) schreiben wir diesen ins ListviewItem
      44. LItm.SubItems.Add(ex.Message) '
      45. ResultList.Items.Add(LItm)
      46. End Try
      47. End Sub


      So nun fehlt nur noch der Kern der Sache. Der Timer mit dem Ping:

      VB.NET-Quellcode

      1. Private Sub PingTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles PingTimer.Tick
      2. Dim myPing As New Ping 'Neue Instanz der PingKlasse erstellen
      3. Dim myPOptions As New PingOptions ' Neue Instanz der PingOptionen Klasse erstellen
      4. Dim myTimeOut = 2000 'UNd das TimeOut auf 2 Sekunden gesetzt(ist optional, bzw kann man auch einstellbar gestalten)
      5. Dim sbuffer As String = "" 'Einen Leeren String für den Buffer
      6. For a = 0 To 31 'Hier befüllen wir den Buffer mit 32 Chars
      7. sbuffer &= "a"
      8. Next
      9. Dim mybuffer() As Byte = System.Text.Encoding.Default.GetBytes(sbuffer) 'Hier wandeln wir den String in ein ByteArray
      10. 'Die Größe des Buffers ist nun 32 Byte
      11. myPOptions.DontFragment = False 'Hier setzen wir die Ping Option
      12. 'Die Daten dürfen fragmentiert werden, diese Eigenschaft ist optional
      13. 'Näheres kommt später
      14. myPOptions.Ttl = Integer.Parse(txtTTL.Text)
      15. 'Hier sezten wir die TimeToLive
      16. 'Auch das benötigen wir für den einfachen Ping eigentlich nicht
      17. '
      18. '####################################################################################
      19. '# Hier kommt der eigentlich Ping request. Wir senden nun synchron an den Host
      20. '# Mit all unseren Gesetzten Optionen
      21. '# PING.Send("IPADRESSE","TIMEOUT","BUFFER","PINGOPTIONEN"
      22. '# Das Resultat kommt in ein PingReply Objekt.
      23. '# Dies enthält nun alle wichtigen Antwort Daten
      24. Dim myPingResult As PingReply = myPing.Send(IpToPing, myTimeOut, mybuffer, myPOptions)
      25. ResultList.Items(0).Text = IpToPing.ToString ' Wir tragen die IP ins erste ITEM, Spalte 1
      26. ResultList.Items(0).SubItems(1).Text = myPingResult.Status.ToString ' Den status (erreichbar/nicht erreichbar) in Spalte 2
      27. ResultList.Items(0).SubItems(2).Text = myPingResult.RoundtripTime.ToString ' Die ResonseTime in Spalte 3
      28. End Sub


      Nun noch ein paar Feinheiten.

      VB.NET-Quellcode

      1. Private Sub BtnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStop.Click
      2. PingTimer.Stop()
      3. BtnStop.Enabled = False
      4. btnStart.Enabled = True
      5. End Sub


      Erklärt sich von selbst.

      Zum Fehler abfangen sollten wir auch noch prüfen ob in den Beiden Textboxen für TTL und RepeatTime auch Integer Werte stehen:

      Im einfachsten Fall tun wir dies im TextChange event und blockieren einfach den StartButton:

      VB.NET-Quellcode

      1. Private Sub txtTTL_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtTTL.TextChanged
      2. btnStart.Enabled = Integer.TryParse(txtTTL.Text, New Integer)
      3. End Sub
      4. Private Sub txtRpt_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRpt.TextChanged
      5. btnStart.Enabled = Integer.TryParse(txtTTL.Text, New Integer)
      6. End Sub


      So.

      Teil I ist damit auch schon vorbei.
      Bei Fragen oder Anregungen einfach posten.

      Dies dient nur als Grundlage, Fehlerbehandlung sollte umfangreicher und besser stattfinden.
      Auch Designtechnisch ist hier nix großes passiert.

      In Teil II - Die Tracert Klasse setzen wir hier wieder an.

      Ich hoffe ein paar können hiervon profitieren

      Gruß Mono
      Das ist meine Signatur und sie wird wunderbar sein!