RSS
StartseiteKnowledge LibraryTop 10Impressum

Die Frage nach der IP

Mit Bordmitteln die öffentliche IP-Adresse hinter einem Hardware-Router ermitteln

Immer mehr Nutzer gehen mit DSL online. Meist erfolgt dieser Zugang über einen Router, mit W-LAN, Firewall und allem was dazu gehört, damit man selbst, seine Familie, Freunde oder WG-Kollegen halbwegs sicher im Internet unterwegs sein können. Damit ist aber auch der Nachteil verbunden, dass man auf dem eigenen Rechner nicht mehr ohne weiteres die öffentliche IP-Adresse in Erfahrung bringen kann, wie bei der klassischen RAS-Einwahl.

Zwar bietet die Software der Router meist ein Menü, unter dem man die öffentliche IP-Adresse abfragen kann, hierzu muss man sich aber erst beim Router anmelden und sich über zig Menüpunkte zur IP-Adresse durchklicken. Diese durch eine VB Anwendung zu ermitteln, kaum denkbar. Dabei weiß jeder Webserver sofort mit welcher IP-Adresse der Besucher unterwegs ist.

Das Script für PHP oder ASP

Genau diesen Umstand können wir uns hier zunutze machen. Alles was es dafür braucht ist entweder eine Seite, die einem die IP-Adresse ausgibt, wie http://myip.tdsw.de/ oder man mietet sich selber ein Webpaket, das über Scripting Fähigkeiten, wie PHP, ASP oder ASP.NET verfügt. Als Script, muss allein die Server-Umgebungsvariable "REMOTE_ADDR" abgefragt und ausgegeben werden.

In PHP:

<?PHP
  header("content-type: text/plain");
  echo getenv("REMOTE_ADDR");
?>

In ASP:

<%
  Response.ContentType = "text/plain"
  Response.Write Request.ServerVariables("REMOTE_ADDR")
%>

Nachdem man das Script auf seinem Webserver veröffentlicht hat, kann man sich das Ergebnis in einem Browser seiner Wahl anzeigen lassen. Genauso können Sie diese einfache Ausgabe in einer VB Anwendung abfragen und weiterverwenden. Wie versprochen, werden hierzu keine externen Komponenten benötigt und auch kein Windows API Aufruf.

Die AsyncRead-Methode eines UserControl

VB hat bereits alles an Bord, um Daten aus dem Internet abzurufen: Die AsyncRead-Methode eines UserControl. Zugleich Gelegenheit, die Abfrage der öffentlichen IP-Adresse in einer einfach zu nutzenden Komponente zu kapseln.

Unsere Komponente bietet die Möglichkeit den Dienst frei festzulegen und die Abfrage synchron oder asynchron auszuführen. Bei letzterem muss die ermittelte IP Adresse über ein Ereignis an die Host-Anwendung übermittelt werden. Kann die IP-Adresse nicht ermittelt werden, wir ein Fehlerereignis ausgelöst. Bei der synchronen Abfrage geschieht dies über die Rückgabe der Request-Methode. Bei Erfolg ist diese "True". Die IP-Adresse ist in beiden Fällen über die Address-Eigenschaft abzufragen.

Das UserControl "AssignedIP"

Die notwendigen Deklarationen:

Option Explicit

Private Const DEFAULT_SERVICE As String = "http://myip.tdsw.de/"

Private p_Service As String
Private p_Address As String

Public Event Resolved(ByRef Address As String)
Public Event Error()

Über die Service-Eigenschaft kann der Dienst festgelegt werden, der die IP-Adresse im reinen Textformat liefert.

Public Property Get Service() As String
  Service = p_Service
End Property

Public Property Let Service(ByVal New_Value As String)
  p_Service = New_Value
  
  PropertyChanged "Service"
End Property

Voreingestellt ist "http://myip.tdsw.de/":

Private Sub UserControl_InitProperties()
  p_Service = DEFAULT_SERVICE
End Sub

Diese Eigenschaft kann bereits zur Designzeit entsprechend gesetzt werden, daher ist es erforderlich diese Änderungen dann auch dauerhaft zu speichern:

Private Sub UserControl_WriteProperties( _
                        PropBag As PropertyBag _
                                )
  PropBag.WriteProperty "Service", _
                        p_Service, _
                        DEFAULT_SERVICE
End Sub

Private Sub UserControl_ReadProperties( _
                        PropBag As PropertyBag _
                                )
  p_Service = PropBag.ReadProperty("Service", _
                                   DEFAULT_SERVICE)
End Sub

Das Herzstück ist die Request-Methode, die die Abfrage der IP-Adresse startet. Über den Parameter "Async" kann optional festgelegt werden, dass diese Abfrage asynchron ausgeführt wird, die Methode also direkt nach Absetzen der Anfrage zurückkehrt. In diesem Fall gibt die Methode immer "False" zurück. Andernfalls erhält man bei einer erfolgreichen Abfrage "True" und kann über die Address-Eigenschaft die ermittelte IP-Adresse abrufen:

Public Function Request( _
       Optional ByVal Async As Boolean _
                     ) As Boolean
  Dim lRequestFlags As AsyncReadConstants
  
  If Async Then
    lRequestFlags = vbAsyncReadForceUpdate
  Else
    lRequestFlags = vbAsyncReadForceUpdate Or _
                 vbAsyncReadSynchronousDownload
  End If
  
  On Error Resume Next
  UserControl.AsyncRead p_Service, _
                        vbAsyncTypeByteArray, _
                        "RemoteIP", _
                        lRequestFlags
  
  Request = CBool(Err.Number = 0)
End Function

Public Property Get Address() As String
  Address = p_Address
End Property

Das AsyncReadComplete-Ereignis des UserControl wird ausgelöst, wenn alle Daten, also unsere IP-Adresse, empfangen wurden. Die Zeichenfolge wird als ANSI Byte-Array übertragen und muss in eine VB-Unicode Zeichenfolge konvertiert werden:

Private Sub UserControl_AsyncReadComplete( _
                  AsyncProp As AsyncProperty _
                            )
  On Error Resume Next
  p_Address = StrConv(AsyncProp.Value, vbUnicode)
  
  If CBool(Err.Number) Then
    RaiseEvent Error
  Else
    RaiseEvent Resolved(p_Address)
  End If
End Sub

... in der Anwendung

Das Steuerelement auf einem Formular platzieren und Ihnen steht eine komfortable Möglichkeit zur Verfügung, die öffentliche IP-Adresse in Ihrer Anwendung abzufragen:

Me.MousePointer = vbHourglass
If AssignedIP.Request() Then
  MsgBox "Zugeteilte IP-Adresse: " & AssignedIP.Address, _
         vbInformation Or vbOKOnly, _
         Me.Caption
           
End If
Me.MousePointer = vbDefault