Xcode: Netzwerkschnittstellen auslesen und einzeln ansprechen

Profilfoto von comfreak

VonAntwort von comfreak

Hallo zusammen,

habe da eine kleine Frage, die ich leider mittels Google bisher nicht lösen konnte.
Ich möchte in Xcode ein kleines Programm schreiben und muss dazu die Netzwerkschnittstellen (LAN, WLAN, etc) auslesen und danach diese einzeln wieder ansprechen können.
Wie kann ich das am einfachsten in Xcode erreichen?

Vielen Dank für eure Hilfe,
Gruß comfreak

Profilfoto von hirnstroem

hirnstroem

Hallo comfreak,

am einfachsten greifst du auf die Shell zurück und da würde sich doch der Befehl ‘ifconfig’ anbieten.

Aber es gibt natürlich noch zig weitere Möglichkeiten:

z.B.:

—————
struct ifaddrs *ifap;
getifaddrs(&ifap;);
// durch ifap iterieren, sofern kein Null Pointer…und den Rückgabewert von getifaddrs sollte auch noch geprüft werden
freeifaddrs(ifap);
—————

Oder plattformunabhängig mit Java z.B:

—————
import java.net.NetworkInterface;

// ...

Enumeration enum = NetworkInterface.getNetworkInterfaces();
while (enum.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface)enum.nextElement();
Enumeration inetEnum = ni.getInetAddresses();
}
—————

Oder du benutzt das IOKit: http://developer.apple.com/documentation/devicedrivers/conceptual/IOKitFundamentals/Introduction/Introduction.html (IOEthernetInterface.h <- Header File anschauen)

Damit das aber jetzt keine endlos lange Liste wird, frage ich lieber nach, was genau mit den Netzwerkschnittstellen passieren soll? Und mit welcher Programmiersprache überhaupt?

Grüsse
hirnstroem

Profilfoto von comfreak

comfreak

Hallo,

ich möchte das Programm in Xcode in Objective-C schreiben.
Das Programm soll nur oberflächlich die Schnittstellen auslesen, damit ich dann nacher über die in einer ComboBox ausgewählte ausgelesen Schnittstelle zum Beispiel einen Download starten kann. Also wähle ich zum Beispiel “eth0” oder so aus und wenn ich dann auf einen Button klicke, dann startet der eben z.B. einen Download über diese Schnittstelle.
Daher möchte ich die Schnittstellen so auslesen, dass ich sie gleich in einer ComboBox anzeigen lassen kann.

Gruß comfreak

Profilfoto von hirnstroem

hirnstroem

#include <stdio.h>

#include <CoreFoundation/CoreFoundation.h>

#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>

static CFMutableDictionaryRef GetEthernetInterfaceDict();

static CFMutableDictionaryRef GetEthernetInterfaceDict()
{
    return IOServiceMatching(kIOEthernetInterfaceClass);
}

^^ diese Funktion gibt ein veränderbares Wörterbuch mit Informationen zu allen Netzwerkschnittstellen zurück (oder Null). Am besten iterierst du über dieses Wörterbuch und gibst ein Paar Nachrichten auf der Konsole aus, um zu erfahren, wass denn da alles für Schlüssel und Werte drin sind. Eventuell muss das Wörterbuch noch in einen Array umgewandelt werden, damit es auf das Auswahlfeld gebunden werden kann.

Ich hoffe das hilft dir weiter.

PS: Code - auch wenn nicht viel - ungetestet ;-)

Profilfoto von hirnstroem

hirnstroem

Von comfreak • Mittwoch, 05. August 2009, 06:43 Uhr

Gibt dieser Code dann nur die Ethernet Schnittstellen aus oder nennt sich die Funktion einfach nur so?

Die Funktion gibt die Ethernet Schnittstellen aus.

Für alle Netzwerkschnittstellen:

IOServiceMatching(kIONetworkInterfaceClass)

(die wollte ich eigentlich auch, aber der Morgen bekämpft mich zuweilen)

Profilfoto von comfreak

comfreak

Von hirnstroem • Mittwoch, 05. August 2009, 05:24 Uhr

diese Funktion gibt ein veränderbares Wörterbuch mit Informationen zu allen Netzwerkschnittstellen zurück (oder Null). [..] Eventuell muss das Wörterbuch noch in einen Array umgewandelt werden, damit es auf das Auswahlfeld gebunden werden kann.

Und wie kann ich das umwandeln?
Arbeite erst seit kurzem mit Objective-C und hab mich bisher noch nicht mit dem umwandeln von Datentypen beschäftigt..

Gruß comfreak

Profilfoto von hirnstroem

hirnstroem

Entweder über Schlüssel oder Werte iterieren, und bei jedem Durchgang das aktuelle Objekt in einen zuvor erstelltes Array (MutableArray) legen.
Oder per “CFDictionaryGetKeysAndValues” die Schlüssel und Werte in ein separates Array schreiben.

Und - da führt kein Weg dran vorbei - ganz viel Dokumentation lesen, z.B.: http://developer.apple.com/documentation/CoreFoundation/Reference/CoreFoundation_Collection/index.html#//apple_ref/doc/uid/TP40003849

Profilfoto von comfreak

comfreak

Ok, das werde ich bei Gelegenheit machen.
Nun noch eine anschießende Frage: Wie kann ich dann eine Schnittstelle ansprechen, die ich vorher manuell angegeben habe?
Ich möchte über diese Schnittstelle einen Server kontaktieren und dann den Output in einer Datei speichern (was beim Download einer Datei ja die Datei wäre oder z.B. eine html-Seite).
Oder gäbe es da auch eine einfachere Möglichkeit?

Vielen Dank,
Gruß comfreak

Profilfoto von hirnstroem

hirnstroem

Manuelles ansprechen (ohne vorheriges Auslesen aller Schnittstellen, weil da hat man ja schon alles von Belang):

CFMutableDictionaryRef matchingDict = IOBSDMatching("en0"); // en0 ist Ethernet Schnittstelle mit ID 0

Aktiviert wird das Interface (sofern nicht bereits aktiviert) per:

enable(IONetworkInterface *) // IONetworkController

Das Herunterladen ist so eine Sache. Da lassen sich Daten streamen, direkt herunterladen, in einem Thread…Service….je nach dem. Am Einfachsten:

+ (id)dataWithContentsOfURL:(NSURL *)aURL // NSData

Je nach Architektur wird dann allerdings der Main Thread (darin läuft die Applikation) stillgelegt, solange bis der Download fertig ist (keine Benutzereingaben etc. mehr möglich).

http://developer.apple.com/networking/ (hier sind zig Beispiele mit Source Code zu finden, was sicherlich hilfreicher ist als meiner Einer, welcher nicht einmal einen Mac in der Nähe hat :-P)

Profilfoto von hirnstroem

hirnstroem

import java.io.*;
import java.net.*;
import java.util.Enumeration;

class FileDownload {

  public static void main(String[] args) throws IOException {

    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader in = new BufferedReader(isr);

    System.out.println("Below a List of available Network Interfaces is shown: \n");
    Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();    
    while ( networkInterfaces.hasMoreElements() ) {
      System.out.println(((NetworkInterface)networkInterfaces.nextElement()).getName());
    }
    
    System.out.println("\n\nEnter a Network Interface Name: ");
    NetworkInterface aNetworkInterface = NetworkInterface.getByName(in.readLine());

    if ( aNetworkInterface != null ) {            
      System.out.println("Enter a URL (including the File Name): ");
      DownloadThread aDownloadThread = new DownloadThread(in.readLine(), aNetworkInterface);
      System.out.println("Downloading file…");
      try { Thread.sleep(2000); }
      catch(Exception e) {/*do nothing*/}
      aDownloadThread.start();      
      while ( aDownloadThread.isAlive() ) {
        try { Thread.sleep(500); }
        catch(Exception e) {/*do nothing*/}
      }
      System.out.println("Download finished.");
    }
    else {
      System.out.println("Could not find Network Interface.");
    }
    System.out.println("Application terminating…");
  }

  // DownloadThread
  private static class DownloadThread extends Thread {
    private String url;
    private NetworkInterface networkInterface;

    public DownloadThread(String aUrl, NetworkInterface aNetworkInterface) {
      url = aUrl;
      networkInterface = aNetworkInterface;
    }

    public void run() {
      Enumeration inetAddresses = networkInterface.getInetAddresses();

      try {
        Socket socket = new Socket((InetAddress)inetAddresses.nextElement(), 8080);
        if ( !socket.isConnected() ) {
          socket.connect(socket.getLocalSocketAddress(), 2000);
          if ( !socket.isConnected() ) {
            System.out.println("Could not connect.");
          }          
        }
        else {
          String receivedData;
          URL aUrl = new URL(url);
          InputStream is = aUrl.openStream();
          DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
          while ( (receivedData = dis.readLine()) != null ) {
            System.out.println(receivedData);
          }
          is.close();
        }
      }
      catch(Exception e) {
        System.out.println("Error = " + e.toString());
      }
    }
  } // DownloadThread
} // FileDownload


Verwendung (über Konsole):

javac FileDownload.java // zum kompilieren
java FileDownload // für die Ausführung


Erklärung:

Die Applikation gibt zuerst die Namen aller Netzwerkschnittstellen aus und verlangt anschliessend nach der Eingabe eines solchen Namens. Danach wird nach der URL gefragt und ein Thread erzeugt, welcher die Datei herunterlädt und deren Inhalt ausgibt, sofern dies möglich ist, ansonsten gibt es eine Fehlermeldung.

PS: Der Code ist keinesfalls als Referenz gedacht, da doch einige unschönheiten (Programmierparadigma, Fehlerbehandlung und vieles mehr) enthalten sind und überhaupt nicht sichergestellt wird, dass die Daten über die richtige Schnittstelle abgeholt werden…aber immerhin ein grobes Grundgerüst, welches als Einstieg hilfreich sein könnte.

 

sierra2

Von comfreak • Montag, 03. August 2009, 08:02 Uhr

Hallo,

wenn die Lösung so einfach ist, dass man mir schon Bücher empfiehlt, dann kann man mir doch sicher auch einfacher helfen…

Gruß comfreak

Bevor Du den Programmierkurs gratis im Forum machst - nochmal das Buch von Aaron Hillegass ist für jeden Entwickler empfohlen.
Der Mann war während Jahren - am Schreiben der Dokumentation für Openstep und macht jede Menge Trainings für Entwickler.
Du sparst Jahre - die in der Schweiz keine 10 Entwickler haben.
http://www.bignerdranch.com/instructors/hillegass.shtml

Profilfoto von comfreak

comfreak

Von sierra2 • Donnerstag, 06. August 2009, 17:57 Uhr
Von comfreak • Montag, 03. August 2009, 08:02 Uhr

Hallo,

wenn die Lösung so einfach ist, dass man mir schon Bücher empfiehlt, dann kann man mir doch sicher auch einfacher helfen…

Gruß comfreak

Bevor Du den Programmierkurs gratis im Forum machst - nochmal das Buch von Aaron Hillegass ist für jeden Entwickler empfohlen.
Der Mann war während Jahren - am Schreiben der Dokumentation für Openstep und macht jede Menge Trainings für Entwickler.
Du sparst Jahre - die in der Schweiz keine 10 Entwickler haben.
http://www.bignerdranch.com/instructors/hillegass.shtml

Solche Bücher besitze ich schon und das ist gut, aber wir sind (mittlerweile) auf Java umgestiegen und sind der Lösung schon nahe bessergesagt haben wir sie schon.

Gruß comfreak

Anmelden um neue Antworten zu verfassen

Allegra Leser! Nur angemeldete Nutzer können bei diesem Beitrag Antworten hinterlassen. Jetzt kostenlos registrieren oder mit bestehendem Benutzerprofil anmelden.