• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

Netzwerkschnittstellen auslesen und ansprechen

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Ach der meint eine Art Download-dispatcher?
Ich dachte der wollte die IP Pakete auf zwei Routen aufteilen. :D

Ooh Wee...

DAS ist natürlich was anderes, aber bestimmt auch nicht vollkommen unmöglich -- ich denke, TCP/IP gibt das her.

Dazu müsstest Du auf dem Mac aber sicher Deine eigene NKE schreiben.

EDIT:EIN Paket auf ZWEI Routen geht natürlich nicht.
Alex
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Zu dem verteilten downloaden:
Aber wie willst du dem Zielhost sagen, dass der die Datenpakete aufteilen und an zwei verschiedenen IP Adressen schicken soll?

Indem ich dem ersten Download sage: "Downloade dieses und beginne bei 0" und dem zweiten sage ich: "Downloade dieses und beginne bei 10000" (50%). Kann man bei YouTube und Co auch bemerken, wenn man im Video springt, das noch nicht geladen wurde. Außerdem können das Download Manager auch, wieso sollte es dann nicht funktionieren?

Übrigens, was sich viele hier vorstellen ist, dass ich einen Loadbalancer programmieren möchte.
Das habe ich nicht vor, ich möchte lediglich einen Download in zwei Hälften aufteilen und dann je eine Hälfte auf eine Schnittstelle verteilen und wenn beide fertig sind, die Datei lokal zusammensetzen (so wie es ein Dowload Manager auch macht).

Gruß comfreak
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Indem ich dem ersten Download sage: "Downloade dieses und beginne bei 0" und dem zweiten sage ich: "Downloade dieses und beginne bei 10000" (50%). Kann man bei YouTube und Co auch bemerken, wenn man im Video springt, das noch nicht geladen wurde. Außerdem können das Download Manager auch, wieso sollte es dann nicht funktionieren?

Übrigens, was sich viele hier vorstellen ist, dass ich einen Loadbalancer programmieren möchte.
Das habe ich nicht vor, ich möchte lediglich einen Download in zwei Hälften aufteilen und dann je eine Hälfte auf eine Schnittstelle verteilen und wenn beide fertig sind, die Datei lokal zusammensetzen (so wie es ein Dowload Manager auch macht).

Gruß comfreak

Das geht alles. Aber nicht jeder HTTP Server unterstützt das "Range" Headerfeld.

Und wie gesagt, wenn Du jetzt willst, das zwei Pakete mit der Identischen Destination IP unterschiedlich geroutet werden musst Du -- meiner Vorstellung nach -- sehr tief in's System gehen.

Alex
 

drlecter

Wöbers Rambur
Registriert
04.11.06
Beiträge
6.442
ich hatte dir das oben schon gesagt wie du das realisieren kannst. Du kannst die Routen zu den IPs von Hand setzen. Du könntest auch einfach ein Script schreiben, was auf eine URL ein nslookup macht, diese IP dann über das GW von dir routet und nach Abschluss des downloads wieder die Route auf Default setzt (oder ggf. direkt einfach youtube usw. auf ein Interface legt).
 

Jamsven

London Pepping
Registriert
21.11.07
Beiträge
2.046
Das geht alles. Aber nicht jeder HTTP Server unterstützt das "Range" Headerfeld.

Alex

So sehe ich das auch, denn nicht jeder Server braucht das. Da solche aktivierten Features auch mehr potenzielle Sicherheitslöcher haben können werden das wohl einige ausschalten.
ich hatte dir das oben schon gesagt wie du das realisieren kannst. Du kannst die Routen zu den IPs von Hand setzen. Du könntest auch einfach ein Script schreiben, was auf eine URL ein nslookup macht, diese IP dann über das GW von dir routet und nach Abschluss des downloads wieder die Route auf Default setzt (oder ggf. direkt einfach youtube usw. auf ein Interface legt).
Hat aber den Nachteil, das alles unter dieser IP umgeleitet wird und du Probleme bei paralellen Downloads hast.
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
So sehe ich das auch, denn nicht jeder Server braucht das. Da solche aktivierten Features auch mehr potenzielle Sicherheitslöcher haben können werden das wohl einige ausschalten.

Solche Features sind aber auch nötig, um einen Download fortzusetzen und die meisten Server bieten diese Features. Wenn nicht ist es (momentan) auch nicht so tragisch..

below schrieb:
Und wie gesagt, wenn Du jetzt willst, das zwei Pakete mit der Identischen Destination IP unterschiedlich geroutet werden musst Du -- meiner Vorstellung nach -- sehr tief in's System gehen.

Ich bezweifel das. VirtualBox (mein Beispiel ;)) ist auch nur eine "kleine" Software, die jedenfalls keine Admin Rechte braucht, also kann es SO tief nicht sein..

Übrigens habe ich es vorhin mit Java probiert (wo ich ein bisschen mehr Erfahrung habe) und dort hat es einwandfrei geklappt, zumindest das Auslesen.. Am Schreiben bin ich noch dran ;)

Gruß comfreak
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Möchte noch kurz den Java Code (zum Nachvollziehen) hier her kopieren.
Der hat mir als Leitfaden geholfen, allerdings funktioniert die "DownloadThread"-Klasse noch nicht ganz..

Code:
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

Gruß comfreak
 

StephanG

Normande
Registriert
07.11.07
Beiträge
582
Ob das in Java so ganz einfach geht, weiß ich nicht. Müsste man sicherlich mal ausprobieren, aber ich könnte mir schon vorstellen, dass es da hier und da zu Problemen kommen kann. Ich hatte etwas ähnliches mal bei einem Kunden gesehen, allerdings dort im großen Netzwerk und das machte irgendwann Probleme. Wobei es auch nicht beabsichtigt war in der Konfiguration.

Bzgl. VirtualBox handelt es sich ja um virtuelle Interfaces, die einfach auf ein richtiges Interface aufgesetzt werden. Davon kannst du massig anlegen, aber sie bleiben nur einem Interface hinterlegt.

Der verteilte Download, also parallel mit mehreren Connections, muss wie schon gesagt vom Server unterstützt werden.

Auch ist es möglich über eine Leitung den Upstream und über eine andere den Downstream laufen zu lassen (mal bei Cisco schauen...). Von Haus aus einen Downstream auf zwei Leitungen zu verteilen geht so nicht.

Aber zurück zum Problem. ;)
Da wirst du mit herkömmlichen Mitteln in Cocoa nicht weiter kommen. Wenn du solche Sachen realisieren willst, dann wirf einen Blick in den NKE Guide, evtl. hilft das weiter. Ich weiss allerdings nicht ob OS X da nicht (aus gutem Grund) einen Riegel vor schiebt.
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.059
Möchte noch kurz den Java Code (zum Nachvollziehen) hier her kopieren.
Der hat mir als Leitfaden geholfen, allerdings funktioniert die "DownloadThread"-Klasse noch nicht ganz..
Das ist auch kein Wunder, daß das nicht funktioniert. Denn in dem Programmcode wird schlußendlich ein Socket mit der IP-Adresse Deiner Netzwerkinterfaces geöffnet, d.h. Du versuchst mit Deinem eigenem Computer eine Verbindung aufzubauen. Da es sich um Port 8080 handelt, vermute ich, daß Du da einen Proxy laufen hast.
Code:
Socket socket = new Socket((InetAddress)inetAddresses.nextElement(), 8080);
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
zgl. VirtualBox handelt es sich ja um virtuelle Interfaces, die einfach auf ein richtiges Interface aufgesetzt werden. Davon kannst du massig anlegen, aber sie bleiben nur einem Interface hinterlegt.

Ich konnte, wie bereits gesagt, die virtuelle Schnittstelle einer echten zuweisen. Also konnte ich sagen virtuelleSchnittstelle1 läuft über WLAN, wobei ich normalerweise über LAN arbeite, das die Standardverbindung ist. VirtualBox hat also bestimmt, über welches (echte) Interface der Traffic der virtuellen Maschine läuft.

Gruß comfreak
 
Zuletzt bearbeitet:

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Das ist auch kein Wunder, daß das nicht funktioniert. Denn in dem Programmcode wird schlußendlich ein Socket mit der IP-Adresse Deiner Netzwerkinterfaces geöffnet, d.h. Du versuchst mit Deinem eigenem Computer eine Verbindung aufzubauen. Da es sich um Port 8080 handelt, vermute ich, daß Du da einen Proxy laufen hast.
Code:
Socket socket = new Socket((InetAddress)inetAddresses.nextElement(), 8080);

Dieser Code heißt lediglich "erstelle einen Socket an dieser Schnittstelle am Port 8080"..
Übrigens ist er nicht von mir, den habe ich per Google nach langem Suchen gefunden ;)

Gruß comfreak
 
Zuletzt bearbeitet:

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Ob das in Java so ganz einfach geht, weiß ich nicht. Müsste man sicherlich mal ausprobieren, aber ich könnte mir schon vorstellen, dass es da hier und da zu Problemen kommen kann.

Wie gesagt, das Auslesen der Schnittstellen funktioniert per Java bestens. Am Senden und Empfangen von Daten bin ich noch dran.. Aber Beispiele (unter anderem auch das genannte) beweisen, dass es funktioniert. Ich möchte allerdings das ganze in Obj-C machen, da Cocoa Apps schneller starten und besser aussehen, als Java Apps.
Im Anhang noch einen kleinen Screenshot von VirtualBox

Gruß comfreak

EDIT: Ich möchte es noch einmal sagen: Ich möchte keine Pakete auf verschiedene Schnittstellen routen, sondern verschiedene Teildownloads starten.
 

Anhänge

  • Bild 2.png
    Bild 2.png
    114,6 KB · Aufrufe: 78
Zuletzt bearbeitet:

drlecter

Wöbers Rambur
Registriert
04.11.06
Beiträge
6.442
... VirtualBox hat also bestimmt, über welches (echte) Interface der Traffic der virtuellen Maschine läuft.

Gruß comfreak
Nein, du hast VB gesagt, welches Interface es für den Trafic benutzen soll. Das ist dann einfach ein Default Route Eintrag und gut ist.
Warum machst du es dir denn so umständlich? Du kannst doch auch einfach grob mittels AppleScript/PERL usw:
1. angeben welche Schnittstelle benutzt werden soll
2. Übergabe der URL (wenn nur ein Download stattfinden soll)
3. ermitteln der IP der Schnittstelle
4. ermitteln der IP der Ziel URL
5. setzten der Route zur Ziel URL über die Schnittstelle
6. starten des Downloads (curl, wget usw).
Dabei kannst du auch Passwörter usw. übergeben und gut ist und du brauchst nicht mit Sockets hantieren. wget und co. beherschen auch resume bei Downloads, wenn das auch von der Gegenseite unterstützt wird.
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Nein, du hast VB gesagt, welches Interface es für den Trafic benutzen soll. Das ist dann einfach ein Default Route Eintrag und gut ist.
Warum machst du es dir denn so umständlich? Du kannst doch auch einfach grob mittels AppleScript/PERL usw:
1. angeben welche Schnittstelle benutzt werden soll
2. Übergabe der URL (wenn nur ein Download stattfinden soll)
3. ermitteln der IP der Schnittstelle
4. ermitteln der IP der Ziel URL
5. setzten der Route zur Ziel URL über die Schnittstelle
6. starten des Downloads (curl, wget usw).
Dabei kannst du auch Passwörter usw. übergeben und gut ist und du brauchst nicht mit Sockets hantieren. wget und co. beherschen auch resume bei Downloads, wenn das auch von der Gegenseite unterstützt wird.

Aber ich kann keine Downloads aufteilen und wenn dann nachher nicht mehr zusammensetzen..

Gruß comfreak
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Klar. Curl unterstützt den range header. Ist nur die Frage, ob der destination Server das versteht.

Alex

Der Ansatz gefällt mir trotzdem, wäre es möglich diesen Skript mit Daten per Cocoa App zu füttern und dann nachher dessen Output-Dateien mit der Cocoa App zusammenfügt?

Gruß comfreak
 

nevermind

Bismarckapfel
Registriert
19.12.07
Beiträge
142
Nochmal kurz zu dem Java-Code, den du gepostet hast:
Das kann nie so funktioniert haben, wie du dir das vorstellst.

1) die Zeile
Code:
Socket socket = new Socket((InetAddress)inetAddresses.nextElement(), 8080);
macht genau das, was tjp oben schrieb, du verbindest mit einer lokalen ip auf 8080.

2) Die weiter unten benutzte URL Klasse sitzt schon auf bzw. über der Protokollschicht. Auf die verwendeten Sockets hast Du afaik keinen Einfluss.

3) Mit dem oder dem Konstruktor könnte das schon eher klappen. Dann bleibt dir noch das Problem, dass Du zwar einen tcp Socket mitsamt io Streams, aber kein Protokoll mehr hast. Dürfte aber für http nicht so schwer sein.
 

comfreak

deaktivierter Benutzer
Registriert
05.11.08
Beiträge
959
Das gepostete Java Beispiel war nur ein Beispiel für mich, damit ich wusste, wie ich das am Besten handle..
Das es nicht funktionieren kann, habe ich bemerkt.
Wenn ich das richtig verstanden habe, dann richte ich einen Socket mit der genannten Zeile ein und kopple sie an eine Schnittstelle mit "Socket.bind(Schnittstelle)". Das habe ich in einem Versuch auch probiert, aber dem Compiler hat der Datentyp nicht gefallen, als ich die ComboBox ausgelesen und dessen Wert in die "bind"-Funktion eingefügt habe.
Wie kann ich das denn am Einfachsten machen, damit ich wenigstens mal mit einem Server verbinden kann, um den Code zu testen?

Gruß comfreak
 

nevermind

Bismarckapfel
Registriert
19.12.07
Beiträge
142
Wie gesagt, dein (echtes) problem ist nicht die combobox, sondern eher das fehlende protokoll.

Für die Combobox (ich geh von Swing aus) ist es am schnellesten die Interfaces in einen Vector zu stecken, den Vector dann in den Constructor der JCombobox. Die Combobox nutzt dann das toString() der Klasse NetworkInterface, was den Vorteil hat, dass du auch deren ips siehst.

um zu verbinden kannst du dann sowas machen:

Code:
JTextField txt;
JCombobox cBox;

...

URL url = new URL(txt.getText());
int remPort = url.getPort() < 0 ? 80 : url.getPort();
int locPort = 7777;
InetAddress lAddr = ((NetworkInterface)cBox.getSelectedItem()).getInetAddresses().nextElement();

sock = new Socket(url.getHost(), remPort, lAddr, locPort);
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));

wr.write("GET " + url + " HTTP/1.1\r\n");
wr.write("\r\n");
wr.flush();

String line;
while ((line = rd.readLine()) != null)
	System.out.println(line);

sock.close();

Der Haken an der Geschichte ist halt, dass das Protokoll minimal reingerotzt ist, und die komplette http response über einen CharacterStream auf system.out landet. Ist noch viel arbeit, und lohnt sich eigtl nicht.

Btw, der Code ist schnell zusammenkopiert, und ungetestet, es sollte aber etwa so funktionieren.