IP Range durchlaufen und speichern



  • Das eigentliche Problem ist nicht das durchlaufen der fertigen Liste, sondern die einzelnen IPs zu ermitteln, die dann jeweils abgespeichert werden sollen.
    Also die geschachtelten for-Schleifen...
    Wenn ich meinen string in int gewandelt habe, muss ich dann für jedes Oktett eine Variable anlegen und diese von hinten beginnend hochzählen?

    Sorry, aber da fehlt mir gerade ein bisschen Abstraktion.



  • Du mußt einfach 4 (verschachtelte) Schleifen verwenden:

    std::vector<std::string> v;
    std::ostringstream s;
    for(int a=0; a<=255; a++)
      for(int b=0; b<=255; b++)
        for(int c=0; c<=255; c++)
          for(int d=0; d<=255; d++)
          {
             s.str(""); // erst löschen
             s << a << '.' << b << '.' << c << '.' << d;
             v.push_back(s.str());
          }
    }
    

    Nun noch die Schleifenanfänge bzw. -enden anpassen und fertig ist's...

    Vorsicht: obiges nicht unangepaßt laufenlassen: ~4,2 Milliarden Werte !!!



  • Ein frohes neues Jahr euch allen!

    @Th
    Super, das hilft mir weiter.
    Aber nochmal zu den sstreams. Wie genau kann ich denn die IP-String mittels ostringstream in 4 int-Variablen abspeichern?



  • smooth_op schrieb:

    Ein frohes neues Jahr euch allen!

    @Th
    Super, das hilft mir weiter.
    Aber nochmal zu den sstreams. Wie genau kann ich denn die IP-String mittels ostringstream in 4 int-Variablen abspeichern?

    😕
    Hi,

    also irgendwie habe ich den Eindruck, dass Du nicht weißt, was Du willst.
    Willst Du die IPs nun als Zeichenketten oder als Wert-Tupel ablegen ?
    Ich würde Dir ja Letzteres empfehlen, weil Du die Werte so gleich verfügbar hast, aber der Weg (4 unsigned char) -> string -> (4 int) ist jedenfalls höchstwahrscheinlich unsinnig.

    Wenn Du natürlich ein Liste abspeichern willst, kannst Du das über ofstream oder cout machen ... und die Werte für die Bearbeitung in einem Vektor speichern.

    Vermutlich ist aber sogar diese Abspeicherung überflüssig, weil diese 4-fachschleife jederzeit wiederholbar ist ... ich weiß nicht, wozu man sich diese Werte überhaupt merken soll. Das ist ebenso sinnvol, wie eine Liste aller ganzen Zahlen von 1 bis 1000000 abzuspeichern.

    Gruß,

    Simon2.



  • Th schrieb:

    Du mußt einfach 4 (verschachtelte) Schleifen verwenden:

    std::vector<std::string> v;
    std::ostringstream s;
    for(int a=0; a<=255; a++)
      for(int b=0; b<=255; b++)
        for(int c=0; c<=255; c++)
          for(int d=0; d<=255; d++)
          {
             s.str(""); // erst löschen
             s << a << '.' << b << '.' << c << '.' << d;
             v.push_back(s.str());
          }
    }
    

    Nun noch die Schleifenanfänge bzw. -enden anpassen und fertig ist's...

    Vorsicht: obiges nicht unangepaßt laufenlassen: ~4,2 Milliarden Werte !!!

    das wird so nicht klappen...

    beispielsweise, wenn du alle IPs von 127.0.0.1 bis 192.168.24.5 durchlaufen willst... deine Schleife würde dann so aussehen:

    std::vector<std::string> v;
    std::ostringstream s;
    for(int a=127; a<=192; a++)
      for(int b=0; b<=168; b++)
        for(int c=0; c<=24; c++)
          for(int d=1; d<=5; d++)
          {
             s.str(""); // erst löschen
             s << a << '.' << b << '.' << c << '.' << d;
             v.push_back(s.str());
          }
    }
    

    ich denke, du wirst selber merken, dass bereits 127.0.0.6 nicht mehr erfasst wird



  • Moin Simon,

    ich glaub schon zu wissen was ich will, vielleicht kann ich es nur nicht gut vermitteln 🙂
    Der Benutzer gibt also einen Range in Form "von - bis" an. Dies geschieht im stringFormat.
    Jetzt wandle ich diese 2 strings in 8 ints um(4 für die Start- und 4 für die Endadresse). -> momentanes Problem!
    Danach laufe ich von der Start- bis zu der Endadresse durch und speichere jede einzelne Adresse im Vektor. Das hat mir Th ja schon gezeigt.
    Das ganze müsste doch in etwa so aussehen:

    // Start und End Oktets
    		  int startaddr_okt1(0);
    		  int startaddr_okt2(0);
    		  int startaddr_okt3(0);
    		  int startaddr_okt4(0);
    		  int endaddr_okt1(0);
    		  int endaddr_okt2(0);, 
    		  int endaddr_okt3(0);
    		  int endaddr_okt4(0);
    
     // start und endadresse mit stringstream wandeln
     // ???
    
    		  //IP Adressen durchlaufen und in Vector speichern
    		  for( ; startaddr_okt1 <= endaddr_okt1; ++startaddr_okt1)
    		  {
    			for( ; startaddr_okt2 <= endaddr_okt2; ++startaddr_okt2)
    				for( ; startaddr_okt3 <= endaddr_okt3; ++startaddr_okt3)
    					for( ; startaddr_okt4 <= endaddr_okt4; ++startaddr_okt4)
    
    						// akutelle Adresse in String wandeln und speichern 
    						stream_itos.str(""); // erst loeschen
    						stream_itos << startaddr_okt1 << '.' << startaddr_okt2 
    									<< '.' << startaddr_okt3 << '.' << startaddr_okt4;
    
    						iprange.push_back(stream_itos.str());
    		  }
    

    Moin zwutz,

    meinst du wegen der Klammerung?
    Wie siehts mit meiner Version davon aus, das sollte doch komplett durchlaufen. Bin nur unsicher, ob ich für die Ausdrücke der letzten for-Schleife noch klammern brauche.

    //Edit
    jetzt weiss ich was du meinst. Aber wie kann man tatsächlich alles durlaufen?
    Bin ich eigentlich der erste, der vor dieser Problematik steht? Kommt mir fast so vor.



  • smooth_op schrieb:

    ...
    Der Benutzer gibt also einen Range in Form "von - bis" an. Dies geschieht im stringFormat...

    Ach so !!!
    OK, jetzt habe auch ich es geschnallt. 💡 💡 👍 😋

    Also so wie das klingt, würde ich einen eigenen Datentyp für die IPs nehmen. Entweder hast Du einen "sicheren" 4-Byte-Datentyp zur Hand (ist aber plattformabhängig) oder Du baust Dir eine Klasse

    struct IP {
       unsigned char data[4];
       bool next();
    };
    

    Da kannst Du dann Deine "+1-Mimik mit Überlauf" implementieren (würde aber auch mit einer freien Funktion gehen).

    Das Einlesen würde ich mit dem operator>>(istream&, int&) machen.

    istream& operator(istream& in, IP& ip) {
       char trenner;
       return in >> ip.data[3] >> trenner >> ip.data[2] >> trenner 
          >> ip.data[1] >> trenner >> ip.data[0];
    }
    

    (ungetestet)

    Damit kannst Du direkt aus cin einlesen

    IP ip;
    cin >> ip;
    

    ... oder via einen String (was aber IMHO überflüssig ist)

    IP ip;
    string s;
    cin >> s;
    istringstream istr(s);
    istr >> ip;
    

    Außerdem natürlich auf ifstreams und allen möglichen selbstgebastelten istreams.
    Und das Alles mit der "Standardfehlerbehandlung von operator>>()". (also Abfragen des Stream-Status nach dem Einlesen nicht vergessen)

    Gruß,

    Simon2.



  • Danke Simon, damit werde ichs versuchen. Aud jeden Fall besser, als mit 8 ints rumzumachen.
    Auf was genau muss man den Stream-Status denn checken?

    Ach und den String brauche ich deshalb, weil ich damit später die Client-Adressstruktur für eine Verbindung fülle.

    Wenn jetzt vielleicht noch jemand was zum Durchlaufen des Ranges sagen könnte?

    Grüße,
    smooth



  • smooth_op schrieb:

    ...
    Ach und den String brauche ich deshalb, weil ich damit später die Client-Adressstruktur für eine Verbindung fülle....

    Dafür hast Du doch den operator<<(ostream&, IP const&); 😃 ...

    Das Iterieren sollte nicht das Problem sein:
    - Einfach data[0] erhöhen, wenn da nicht schon 255 drinsteht.
    - Wenn doch, dann data[0]=0 und data[1] erhöhen, wenn da nicht schon 255 drinsteht.
    - Wenn doch, dann data[1]=0 und data[2] ....
    ...
    und wenn IP schon 255.255.255.255 ist, dann liefert next() eben false zurück.

    Gruß,

    Simon2.



  • Alles klar, ich werde mein Glück dann mal versuchen.
    Falls es noch Schwierigkeiten gibt, liest man sich 🙂
    Danke nochmals für die Hilfe.


Anmelden zum Antworten