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:
|
Visual Basic Quellcode
|
1
2
3
4
|
Option Explicit On 'Klar
Option Strict On 'Sollte immer an sein
Imports System.Net
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:
|
Visual Basic Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
Public Class PingForm 'Name der Form
Private WithEvents PingTimer As New Timer 'Wir benutzen für die Anfänger anfangsvariante einen Timer
Private IpToPing As IPAddress 'unsere benötigte globale Variable die die IP Adresse enthalten wird
'Nun kommt das FormLoad Event, dort machen wir nicht viel:
Private Sub PingForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
BtnStop.Enabled = False 'Wir deaktivieren den Stop Button
TxtIP.Text = "www.google.de" 'wir setzen einen Default Wert für die IP/Hostname Textbox
ResultList.View = View.Details 'wir setzen die Listview Ansicht auf Detail
Me.AcceptButton = btnStart 'der Startbutton wird zum acceptButton der Form-> bei Druck auf enter wird dieser ausgelöst
End Sub
'Nun kommen wir zum BtnStart.Click Event. Dieses ist entscheidend:
Private Sub BtnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim Ip As IPAddress() 'Wir deklarieren ein leeres Array von IPAdressen
ResultList.Items.Clear() 'Wir löschen alle Items der Listview
Dim LItm As New ListViewItem 'Wir erstellen ein neues ListviewItem
LItm.Text = TxtIP.Text 'Wir fügen noch einen Text hinzu
'Dieser ist erstmal das eingebene
Try 'Fehler abfangen, falls der Hostname/die website nicht aufgelöst werden kann
If Not IPAddress.TryParse(TxtIP.Text, IpToPing) Then 'Wir versuchen erstmal den Inhalt der Textbox
'in eine IPAdresse zu wandeln
'Dies ist natülich nur erfolgreich wenn wir eine IP eingeben,
'Andernfalls liefert TryParse False zurück und wir versuchen
'den Namen aufzulösen und in das leere IP Array zu schreiben:
Ip = Dns.GetHostAddresses(TxtIP.Text) 'Die DNS Klasse aus dem Framework versucht dies
'schlägt dies Fehl, fliegen wir aus dem Try Block
'und kommen in den Catch Block und geben den Fehler aus
'Nun weisen wir unserer IP Variable die zurückgegebene erste IP Adresse aus unserem IP Array zu
'Da Webseiten auch mehr als eine IP haben können, gibt:
'Dns.GetHostAddresses ein array von IP's zurück, wir nehmen halt einfach die erste
'Da mindest eine aufgelöst werden MUSS
IpToPing = Ip(0)
End If
PingTimer.Interval = Integer.Parse(txtRpt.Text) 'Nun geben wir dem Timer
'sein Intervall indem wir den Text der txtrpt in Integer umwandeln und zuweisen
LItm.SubItems.Add("") 'und 2 Leeren Subitems
LItm.SubItems.Add("")
ResultList.Items.Add(LItm) 'Und fügen diesem der Listview zu
'Die Darstellung ist hier sicher nicht optimal.
BtnStop.Enabled = True 'nun disablen wir den StartButton
btnStart.Enabled = False 'und enablen den Stop Button
PingTimer.Start() 'und starten den Timer
Catch ex As Exception
'Gibts einen Fehler (Name nicht auflösbar) schreiben wir diesen ins ListviewItem
LItm.SubItems.Add(ex.Message) '
ResultList.Items.Add(LItm)
End Try
End Sub
|
So nun fehlt nur noch der Kern der Sache. Der Timer mit dem Ping:
|
Visual Basic Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
Private Sub PingTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles PingTimer.Tick
Dim myPing As New Ping 'Neue Instanz der PingKlasse erstellen
Dim myPOptions As New PingOptions ' Neue Instanz der PingOptionen Klasse erstellen
Dim myTimeOut = 2000 'UNd das TimeOut auf 2 Sekunden gesetzt(ist optional, bzw kann man auch einstellbar gestalten)
Dim sbuffer As String = "" 'Einen Leeren String für den Buffer
For a = 0 To 31 'Hier befüllen wir den Buffer mit 32 Chars
sbuffer &= "a"
Next
Dim mybuffer() As Byte = System.Text.Encoding.Default.GetBytes(sbuffer) 'Hier wandeln wir den String in ein ByteArray
'Die Größe des Buffers ist nun 32 Byte
myPOptions.DontFragment = False 'Hier setzen wir die Ping Option
'Die Daten dürfen fragmentiert werden, diese Eigenschaft ist optional
'Näheres kommt später
myPOptions.Ttl = Integer.Parse(txtTTL.Text)
'Hier sezten wir die TimeToLive
'Auch das benötigen wir für den einfachen Ping eigentlich nicht
'
'####################################################################################
'# Hier kommt der eigentlich Ping request. Wir senden nun synchron an den Host
'# Mit all unseren Gesetzten Optionen
'# PING.Send("IPADRESSE","TIMEOUT","BUFFER","PINGOPTIONEN"
'# Das Resultat kommt in ein PingReply Objekt.
'# Dies enthält nun alle wichtigen Antwort Daten
Dim myPingResult As PingReply = myPing.Send(IpToPing, myTimeOut, mybuffer, myPOptions)
ResultList.Items(0).Text = IpToPing.ToString ' Wir tragen die IP ins erste ITEM, Spalte 1
ResultList.Items(0).SubItems(1).Text = myPingResult.Status.ToString ' Den status (erreichbar/nicht erreichbar) in Spalte 2
ResultList.Items(0).SubItems(2).Text = myPingResult.RoundtripTime.ToString ' Die ResonseTime in Spalte 3
End Sub
|
Nun noch ein paar Feinheiten.
|
Visual Basic Quellcode
|
1
2
3
4
5
|
Private Sub BtnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStop.Click
PingTimer.Stop()
BtnStop.Enabled = False
btnStart.Enabled = True
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:
|
Visual Basic Quellcode
|
1
2
3
4
5
6
7
|
Private Sub txtTTL_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtTTL.TextChanged
btnStart.Enabled = Integer.TryParse(txtTTL.Text, New Integer)
End Sub
Private Sub txtRpt_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRpt.TextChanged
btnStart.Enabled = Integer.TryParse(txtTTL.Text, New Integer)
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