![]() |
IP Range
Ich habe zwei IP Adressen: 192.168.2.100 und 192.168.5.100 Jeder Teil der IP Adresse liegt mir als Integer vor. Wie kann ich jetzt alle IP Adressen in diesem Bereich generieren? Ich habe da irgendwie gerade einen Blackout. :?
|
Re: IP Range
Zitat:
Delphi-Quellcode:
TIP = array[0..3] of Integer;
function makeip(IP: Integer): String; begin result := IntToStr((IP shr 24) and $FF) + '.' + IntToStr((IP shr 16) and $FF) + '.' + IntToStr((IP shr 8) and $FF) + '.' + IntToStr((IP shr 0) and $FF); end; ip1_int := ((ip1[0] and $FF) shl 24) or ((ip1[1] and $FF) shl 16) or ((ip1[2] and $FF) shl 8) or ((ip1[3] and $FF) shl 0); ip2_int := ((ip2[0] and $FF) shl 24) or ((ip2[1] and $FF) shl 16) or ((ip2[2] and $FF) shl 8) or ((ip2[3] and $FF) shl 0); for i := ip1_int to ip2_int do begin Memo1.Lines.Add(IntToStr(makeip(i)); end; |
Re: IP Range
Mann bei dem ganzen rumgeschiebe wird einem ja schwindelig. Aber es geht. Ich glaube, ich hätte da was mit zeichenketten Routinen rumgebastelt. ;) Besten Dank.
|
Re: IP Range
Zitat:
bei ipv6 hättest du schon mehr probleme denn da bräuchtest du erstmal einen 128bit datentyp ;-) |
Re: IP Range
argh. mit fällt grad ein daß der Gebrauch von Integer als datentyp hier zu problemen führen kann. nimm lieber Cardinal/LongWord. aber ansonsten bleibt der code gleich.
|
Re: IP Range
Auch wenn ich es als LongWord deklariere, bekomme ich bei 192.168.2.100 - 255.255.255.255 einen "Range check error".
|
Re: IP Range
Hallo,
wie wär's hiermit:
Delphi-Quellcode:
Anwendung:
type
TIPAddr = array[0..3] of Byte; function GetNext(var IPAddr: TIPAddr): Boolean; var C: Integer; begin Result := True; for C := 3 downto 0 do begin if IPAddr[C] < 255 then begin Inc(IPAddr[C]); Exit; end; IPAddr[C] := 0; end; Result := False; end; function IsBelowOrEqual(IP, Limit: TIPAddr): Boolean; begin Result := (IP[0] shl 24 + IP[1] shl 16 + IP[2] shl 8 + IP[3]) <= (Limit[0] shl 24 + Limit[1] shl 16 + Limit[2] shl 8 + Limit[3]); end;
Delphi-Quellcode:
Gruß
procedure TForm1.Button1Click(Sender: TObject);
var Start, Stop: TIPAddr; begin Start[0] := 192; Start[1] := 168; Start[2] := 0; start[3] := 1; Stop[0] := 192; Stop[1] := 168; Stop[2] := 1; Stop[3] := 10; repeat ListBox1.Items.Add(IntToStr(Start[0]) + '.' + IntToStr(Start[1]) + '.' + IntToStr(Start[2]) + '.' + IntToStr(Start[3])); if not GetNext(Start) then Exit; until not IsBelowOrEqual(Start, Stop); end; xaromz |
Re: IP Range
Hallo mein Lieber ;-)
Hätte nicht gedacht, das auch ich Dir mal weiter helfen kann. Also zuerst die Integer-Werte wandeln is klar denke ich dann kannst du die CreateIPPool benutzen. Wichtig zu wissen: Die CreateIPPool war die Beste von 3 Versuchen mit dem besten zeitlichen Ergebenissen. Von ?.0.0.0 ?.50.255.255 benötigt sie ca 3-4 sek. Je nach CPU. Die anderen Versuche kommen dabei immer so um die 10-15 Sek weg. Villeicht bekommst Du sie ja noch schneller :-). In dem Fall lass von Dir hören.
Delphi-Quellcode:
type
PIp = record p1 : String; P2 : String; p3 : String; p4 : String; end; type MyIP = packed record case Byte of 0: (D,C,B,A : Byte); 1: (dwValue : DWord); end; function SplittIP(IP: string): PIp; var I: Integer; begin Result.p1 := ''; Result.p2 := ''; Result.p3 := ''; Result.p4 := ''; I := 0; repeat Inc(I, 1); if IP[I] <> '.' then Result.p1 := Result.p1+IP[I]; until IP[I] = '.'; repeat Inc(I, 1); if IP[I] <> '.' then Result.p2 := Result.p2+IP[I]; until IP[I] = '.'; repeat Inc(I, 1); if IP[I] <> '.' then Result.p3 := Result.p3+IP[I]; until IP[I] = '.'; repeat Inc(I, 1); if IP[I] <> '.' then Result.p4 := Result.p4+IP[I]; until I = Length(IP); end; function CreateIPPool(sStartIp, sEndIp: String): TStringList; var FromIP, ToIP, IP: MyIP; I: Integer; Adress: PIp; begin Result := TStringList.Create; Adress := SplittIP(sStartIp); with FromIP do begin A := StrToInt(Adress.p1); B := StrToInt(Adress.p2); C := StrToInt(Adress.p3); D := StrToInt(Adress.p4); end; Adress := SplittIP(sEndIp); with ToIP do begin A := StrToInt(Adress.p1); B := StrToInt(Adress.p2); C := StrToInt(Adress.p3); D := StrToInt(Adress.p4); end; for I := FromIP.dwValue to ToIP.dwValue do begin IP.dwValue := I; with IP do Result.Add(Format('%d.%d.%d.%d',[A,B,C,D])); end; end; |
Re: IP Range
man kann es auch kompiliziert machen. Warum addiert ihr nicht gleich mit den Strings ? Ist doch bestimmt kein Aufwand mit IP in Strings zu rechnen ;) (sarkasmus off)
Gruß Hagen
Delphi-Quellcode:
function ToIP(I1,I2,I3,I4: Integer): Cardinal;
function Check(Value: Integer): Byte; begin if (Value >= 0) and (Value <= 255) then Result := Value else raise Exception.Create('ToIP: Values I1,I2,I3,I4 must be in Range 0 upto 255 each'); end; begin Result := Check(I1) shl 24 or Check(I2) shl 16 or Check(I3) shl 8 or Check(I4); end; function IPToStr(Value: Cardinal): String; begin Result := Format('%d.%d.%d.%d', [Value shr 24, Value shr 16 and $FF, Value shr 8 and $FF, Value and $FF]); end; procedure Test; var IP: Cardinal; begin for IP := ToIP(192,168,2,100) to ToIP(192,168,5,100) do Writeln( IPToStr(IP) ); end; |
Re: IP Range
Weil es zulangsam ist!!
Habs grad mal getest: ?.0.0.0 ?.50.255.255: nach über 4 Minuten CPU-Zeit habe ich den das Programm zurückgesetzt... |
Re: IP Range
Guten Morgen.
Kennt denn keiner mehr die Standard-Routinen inet_addr() und inet_ntoa() aus der Unit WinSock? Nachdenkliche Grüße vom marabu |
Re: IP Range
Zitat:
Logisch müssen deiner und mein Code fast identisch effizient sein mit dem Unterschied das es mit garnicht sonderlich um Effizienz im Laufzeitverhalten ging sondern um Effizienz im Sourcecode: sprich Überprüfungen, Vermeidung von Rangecheck Errors, sauberer Borland konformer Source. @marabu: ich weis, denke aber das Luckie das selber machen wollte und eventuell die Unit WinSocks nicht einlinken will. Ich persönlich vermeide es immer WinSocks einzulinken wenn es sich vermeiden lässt. Das Problem ? ganz einfach weil die WinSocks DLLs wohl diejenigen DLLs im Windows sind die am meisten durch 3'rd Party Tools wie Virenscanner, Firewalls, ISDN Treiber, USB Treiber und Trojaner ausgetauscht bzw. sidelinked sind. Man lädt sich also mit WinSocks ohne es zu merken eventuell miesen Code in seine Anwendung. Gruß Hagen |
Re: IP Range
Gut mir ging es damals bei der Entwicklung nur rein um Geschwindigkeit ;-)
|
Re: IP Range
Begründung:
Gruß Hagen
Delphi-Quellcode:
type PIp = record // <- TYPEN fangen mit T an p1 : String; P2 : String; p3 : String; p4 : String; end; // <- Einrückungen, ein Block immer auf gleicher Höhe type MyIP = packed record // <- Einrückungen case Byte of 0: (D,C,B,A : Byte); 1: (dwValue : DWord); end; function SplittIP(IP: string): PIp; // <- String ist eigener Type also S groß bei String var I: Integer; begin Result.p1 := ''; Result.p2 := ''; Result.p3 := ''; Result.p4 := ''; I := 0; repeat Inc(I, 1); if IP[I] <> '.' then // <- Hier AV bei IP = '' Result.p1 := Result.p1+IP[I]; // <- Leerzeichen zwischen Operatoren, alles am + geklitscht until IP[I] = '.'; // <- eine Zeile höher, ist ja wohl nur schlecht .... end; function CreateIPPool(sStartIp, sEndIp: String): TStringList; var FromIP, ToIP, IP: MyIP; // <- Einrückungen I: Integer; Adress: PIp; begin Result := TStringList.Create; // <- Allokation und Rückgabe von komplexen Datentypen sollte man vermeiden // besser ist es als Paramater Strings: TStrings zu übergeben damit der Aufrufer // der Funktion für die Datenhaltung verantwortlich bleibt. Adress := SplittIP(sStartIp); with FromIP do begin // <- begin markiert einen neuen Source/Formtierungs Block, gehört in die nächste // Zeile direkt unter das with. A := StrToInt(Adress.p1); B := StrToInt(Adress.p2); C := StrToInt(Adress.p3); D := StrToInt(Adress.p4); end; Adress := SplittIP(sEndIp); with ToIP do begin A := StrToInt(Adress.p1); B := StrToInt(Adress.p2); C := StrToInt(Adress.p3); D := StrToInt(Adress.p4); end; for I := FromIP.dwValue to ToIP.dwValue do begin // <- begin IP.dwValue := I; with IP do Result.Add(Format('%d.%d.%d.%d',[A,B,C,D])); end; end; |
Re: IP Range
Hai Luckie,
mal eine Frage zu deinen IPs. Warum brauchst Du denn die Adressen aus zwei verschiedenen Netzen? Du hast das Netz 192.168.2.0 und 192.168.5.0 die beiden haben doch nichts miteinaner zu tun. Oder sollte das ganze nur ein Beispiel für deinen "PINGer" sein? |
Re: IP Range
Zitat:
meiner Meinung nach wird string NICHT mit einem großen S geschrieben. Bei delphi ist string ein keyword (wird ja auch fett gemacht), und keywords schreibt man nunmal klein... |
Re: IP Range
das ist tatsächlich eine Ansichtssache. Es ist ein Bezeichner und müsste klein geschrieben werden das stimmmt. Allerdings arbeite ich seit Borland Pascal 4.2 und orientiere mich immer an dem Stil der Borlandianer. Wobei man sagen muß das die letzten Entwicklungen im Hause Borlnd nicht mehr als Referenz dienen können da die Sourcen immer schlechter geworden sind.
Es geht mir aber hier garnicht um solche Kleinigkeiten. Am wichtigsten ist der Fakt das obige Funktion bei IP = '' eine Zugriffsschutzverletzung erzeugen muss !! Übrigens muß ich dazu nichtmal den Source testen, lesen reicht schon aus um dies zu sehen. Sorry, ich möchte hier keinen Krieg anzetteln. Jeder soll nach seinen Ansprüchen seine privaten Source bauen können wie er es möchte. Allerdings ist dies hier ein Forum und viele Anfänger orientieren sich in ihrem Programmierstil an solchen Beispielen wir hier gezeigt. Es ist also in unser aller Interesse wenn wir Sourcecode-technisch hier in der DP ein hohes Niveau hinbekommen könnten. Zb. die Angewohnheit das begin NICHT in einer eigenen Zeile einzurücken ist schätzungsweise höchsten 8-10 Jahre alt. Davor wurde immer das begin eingerückt, bzw. mir persönlich sind keine Sourcen bekannt vor dieser zeit die es nicht einrückten. Leider hat sich diese Unart sehr schnell verbreitet. Ok back to topic now, and sorry Luckie. Gruß Hagen |
Re: IP Range
Zitat:
Der Fainess halbe habe ich jetzt mal kurz das writeln gegen eine TStringList getauscht. Stimmt. Ich konnte die range innherhalb von 4547ms erzeugen. Ich muss aber dazu sagen das die CPU hier, wo ich grad bin etwas lahmer is als meiner da heim. Also könnte sie doch in etwas die Gleiche Effizienz haben. Was die Zugriffsverletzung angeht: Habe ich bis heute nicht gesehen. Das Progie wo ich diesen Code reincomiliert habe läuft schon seit Monaten. Problemlos! |
Re: IP Range
@Sharky: Ja das ist ein Beispiel für mein Pi9ng Programm. Warum sollte man nicht gleich verschiedenen Netze damit durchpingen wollen? ;)
|
Re: IP Range
Hallo Hagen,
Zitat:
Zitat:
Du hast in deinem Beitrag #17 über den Vorbildcharakter von publizierten Quellen für Anfänger geschrieben. Gerade bei Anfängern beobachte ich eine gewisse Dankbarkeit für Hinweise, wie man mit dem Aufruf von wenigen System-Routinen eigenen, mit Schweiß und Tränen geschriebenen Code mehrerer Tage ersetzen kann. Freundliche Grüße vom marabu |
Re: IP Range
Stimmt, die WinSock brauche ich sowieso. Aber man will ja auch noch was lernen.
Aber warum bekomme ich bei 192.168.100.1 - 255.255.255.255 immer noch einen "Fehler bei der Bereichsprüfung"? |
Re: IP Range
Hallo Michael,
welchen Code verwendest du inzwischen? Hast du mal einen Brechpunkt gesetzt? marabu |
Re: IP Range
Zitat:
Du solltest aber in jedem Fall prüfen ob es überhaupt gültige IPs sind. 255.255.255.255 ist zum Beispiel keine gültige Hostadresse. |
Re: IP Range
255.255.255.255 ist wohl die Netsmaske
Grüße Klaus |
Re: IP Range
Oh, bis wann geht denn eine gültige IP Adresse?
|
Re: IP Range
Zitat:
Diese Frage kann man nicht so einfach beantwortet ;-) 255.255.255.255 ist auf jeden Fall die Multicast Adresse. Das IP-Packet wird also in der Theorie an jeden Rechner gesendet. Es gilt eigentlich: Die Hostadresse ist der Teil einer IP-Adresse bei denen die Bits der Subnetmakse 0 sind. IP: 192.168.001.xxx SM: 255.255.255.000 Hostteil der IP: .xxx Netzteil der IP 192.168.001 Es gilt: Wenn alle Bits des Hostteiles 0 sind ist dies die "Netzwerkadresse". Sind alle Bits = 1 ist dies die Broadcastadresse. In diesem Fall ist also: Netzwerkadresse = 192.168.1.0 Broadcastadresse = 192.168.1.255 Gültige Hostadressen sind 192.168.1.1 bis 192.168.1.254 EDIT Lese mal ![]() |
Re: IP Range
Zitat:
Broadcast -> an alle Multicast -> an einige oder viele Grüße Klaus |
Re: IP Range
Marabu hat mich in einer PN einen wichtigen Umstand klargemacht den ich schon wieder vergessen hatte !
Die IPs werden auf einem MS Windows Rechner im WinSocks entgegen dem Standard in einen 4 Bytes Cardinal gespeichert. 130.094.122.195 -> binär 10000010 01011110 01111010 11000011 -> Hex $82,$5E,$7A,$C3 als Cardinal als $825E7AC3. Das Windows WinSocks speichert aber dagegen $C37A5E82 ! Wenn man also mit WinSocks arbeitet und dessen IP Adressdaten zb. Type TInAddr aus inet_ntoa(), oder eben zb. inet_addr(130.094.122.195) benutzen möchte so MUSS man mit htonl() und/oder ntohl() das vorher konvertieren. Das ist wichtig da man ansonsten in einer Schleife ganz falsche Bereiche scannt. In meinen vorherigen Source habe ich mich an die Standardkodierung gehalten und entgegen dem WinSock zb. die Addresse 130.094.122.195 in einen Cardial mit $825E7AC3 umgewandelt. Somit kann man mit diesem Wert auch in einer Schleife arbeiten ohne Probleme. Es ist also kein Fehler wenn
Delphi-Quellcode:
statt 130.094.122.195 eben 195.122.094.130 ausspuckt da bei Verwendung vom WinSock es richtig lauten muß
IPtoStr( inet_addr( PChar('130.094.122.195')));
Delphi-Quellcode:
Gruß Hagen
IPtoStr( ntohl( inet_addr( PChar('130.094.122.195')) ));
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz