| Autor |
Beitrag |
Highspeeder
      
Beiträge: 34
Win 7
Delphi 7 Profesional,Visual Basic
|
Verfasst: Mi 05.07.06 01:58
Hallo, ich will einen IP-Scanner programmieren und aus Geschwindigkeitsgründen mit mehreren Threads arbeiten.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, Sockets, StdCtrls,Strutils, jpeg, ExtCtrls;
type TForm1 = class(TForm) TcpClient1: TTcpClient; Starthost: TEdit; Label1: TLabel; Label2: TLabel; Port: TEdit; Button1: TButton; Memo1: TMemo; Endhost: TEdit; Label3: TLabel; Button2: TButton; Image1: TImage;
procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure weiter; procedure Ipget(Var Hostarray:Array of Integer;Str:String); procedure Ready; procedure ReadyCheck;
private public end;
var Form1: TForm1; Stop: Boolean ; Host1:Array [1..4] of Integer; Host2: Array [1..4] of Integer;
PortAktuell:String; ThreadAnzahl:Integer; IPCounter: Array [1..100] of String; Resultat: Array [1..100] of String; type TMyOwnThread = class(TThread) private CS:TTcpClient; public fertig:Boolean; Nummer:Integer; constructor Create(IPAddr,Port : string); destructor Destroy; override; protected procedure Execute; override; end;
var Thread: array [1..100] of TMyOwnThread;
implementation
{$R *.dfm}
constructor TMyOwnThread.Create(IPAddr,Port : string); begin inherited Create(true); CS := TTcpClient.Create(nil); CS.RemoteHost:=IPAddr; CS.RemotePort:=Port; end;
destructor TMyOwnThread.Destroy; begin CS.Destroy; inherited Destroy; end;
procedure TMyOwnThread.Execute; begin fertig:=false; CS.Active := true;
if CS.Connected = true then begin Resultat[Nummer]:=(CS.RemoteHost+' '+'Port: '+CS.RemotePort+' '+'open'); end else begin Resultat[Nummer]:=(CS.RemoteHost+' '+'Port: '+CS.RemotePort+' '+'closed'); end;
CS.Active := false; fertig:=true; Form1.ReadyCheck; end;
procedure TForm1.Button1Click(Sender: TObject);
Var I:Integer;
begin IpGet(Host1,StartHost.Text); IpGet(Host2,Endhost.Text); Stop:=false; Memo1.Lines.Clear; PortAktuell:=Port.Text; ThreadAnzahl:=0;
While not Stop and (ThreadAnzahl<100) do begin Inc(ThreadAnzahl); IPCounter[ThreadAnzahl]:=IntToStr(Host1[1])+'.'+IntToStr(Host1[2])+'.'+IntToStr(Host1[3])+'.'+IntToStr(Host1[4]);
If (Host1[1]=Host2[1]) and (Host1[2]=Host2[2]) and (Host1[3]=Host2[3]) and (Host1[4]=Host2[4]) then begin stop :=true; end
else begin weiter; end; end;
For I:=1 to ThreadAnzahl do begin Thread[I] := TMyOwnThread.Create(IPCounter[I],PortAktuell); Thread[I].Nummer:=I; Thread[I].Execute; end; end;
procedure TForm1.weiter;
begin
inc(Host1[4]); if Host1[4]>255 then begin Host1[4]:=0; Inc(Host1[3]); end;
if Host1[3]>255 then begin Host1[3]:=0; Inc(Host1[2]); end;
if Host1[2]>255 then begin Host1[2]:=0; Inc(Host1[1]); end;
if Host1[1]>255 then begin Dec(Host1[1]); Stop:=true; end; end;
Procedure TForm1.ReadyCheck; Var I:Integer; Go:Boolean;
begin Go:=true; If Go then Ready end;
procedure TForm1.Ready; Var I:Integer;
begin For I:=1 to ThreadAnzahl do begin Memo1.Lines.Add(Resultat[I]); end; end;
procedure Tform1.Ipget(Var Hostarray:Array of Integer;Str:String);
Var Punkt : Integer;
begin Punkt:=Pos('.',Str); Hostarray[0]:=StrToInt(Copy(Str,1,Punkt-1)); Str:=Copy(Str,Punkt+1,Length(Str)); Punkt:=Pos('.',Str); Hostarray[1]:=StrToInt(Copy(Str,1,Punkt-1)); Str:=Copy(Str,Punkt+1,Length(Str)); Punkt:=Pos('.',Str); Hostarray[2]:=StrToInt(Copy(Str,1,Punkt-1)); Str:=Copy(Str,Punkt+1,Length(Str)); Punkt:=Pos('.',Str); if Punkt=0 then Hostarray[3]:=StrToInt(Str) else Hostarray[3]:=StrToInt(Copy(Str,1,Punkt-1)); end; |
Meine Fragen :
Das sind maximal 100 Threads
1. Wie merke ich, wenn alle Threads fertig sind ?
2. Die Routine müßte dann mehrmals durchlaufen werden, also wenn ich 1000 IP-Adressen scannen will müßte das 10x passieren.
3. Warum bekomme ich eine Fehlermeldung,wenn ich If Thread[I].fertig = false then Go:=false; aufrufe ?
4. Ebenfalls Fehlermeldung bei Methoden Free und Destroy
5. Warum reagiert meine Anwendung bei der Ausführung der Threads nicht mehr ?
muß ich irgendwo synchronise verwenden ?
Vielen Dank schon mal im vorraus
|
|
crowley
      
Beiträge: 406
Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
|
Verfasst: Mi 05.07.06 08:03
kann nicht sofort zu allen deinen fragen eine antwort geben, aber so dreidinge sind mir abgesehen von der unleserlichen formatierung aufgefallen:
ich würde
Delphi-Quelltext 1:
| for i := 0 to ThreadAnzahl - 1 do |
verwenden.
Und ganz wichtiger Hinweis: NIEMALS bei einem Objekt Destroy direkt aufrufen. Free reicht... noch besser ist FreeAndNil.
Public Variablen in Objekten zu verwenden ist gaaaar nicht gut... kapsele das besser in einer Property...
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 05.07.06 08:39
Moin!
Guckst du, threadbasierter Ping ist da schon eingebaut, mit Callback.
cu
Narses
//EDIT: Ah, wer lesen kann, ist klar im Vorteil...  ist ja gar kein Ping...  Sorry.
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Highspeeder 
      
Beiträge: 34
Win 7
Delphi 7 Profesional,Visual Basic
|
Verfasst: Mi 05.07.06 13:09
@Crowley: Danke für den Beitrag.
Bei Threads gibt es folgende Möglichkeit :
Thread.FreeOnTerminate := True;
// FreeOnTerminate bedeutet sobald der Thread die Procedure Execute
// verlassen hat wird sein Speicher wieder von alleine Frei gegeben.
// andernfalls müsste später im Programm Thread.Free aufgerufen werden.
Dadurch wird automatisch auch destroy ausgeführt.
Thread.FreeandNil gibt es nicht.
Na ja..ob ich nun bei 1 oder 0 anfange zu zählen ist eigentlich egal.
@Narses: ein Musterbeispiel für Multithreading.
Durch die Methode synchronize friert meine Anwendung nicht mehr ein.
Allerdings habe ich nun ein neues Problem :
Wenn ich mit 100 Threads arbeite dann kommen unterschiedliche Ergebnisse raus.
TTcpClient meint mal Port 21 ist geschlossen, dann beim nächsten mal Port 21 ist offen.
Mit deiner Ping-Funktion kommt übrigens dann immer ein Timeout.
Kann das sein ? Port 21 offen und keine Pingantwort ?
Funktioniert denn das überhaupt noch richtig ?
Ich meine, wenn ich 100 Hosts anspreche, dann weiß ich ja nie ob der entsprechende Thread gerade bereit ist, um eine Antwort aufzunehmen.
Wenn ich nur 20 Threads nehme dann geht das so einigermaßen.
Vielleicht muß man auch mit TCriticalSection arbeiten...keine Ahnung
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 05.07.06 13:24
Moin!
Es gibt eine Grenze für gleichzeitige TCP-Verbindungen. Deshalb kommt es vermutlich zu dem merkwürdigen Verhalten.
Nebenbei: ich halte es sowieso für fragwürdig, einen Port-Scanner in der von dir eingeschlagenen Weise (und dann noch mit so vielen Threads) zu realisieren.
Schau dir mal NMAP an.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
crowley
      
Beiträge: 406
Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
|
Verfasst: Mi 05.07.06 13:26
schau mal in der Hilfe nach FreeAndNil -> das ist eine Funktion aus SysUtils.pas...
Schlussendlich macht FreeAndNil(MyThread) folgendes:
1.) MyThread.Free;
2.) MyThread := nil;
desweiteren hast du FreeOnTerminate auskommentiert
|
|
Highspeeder 
      
Beiträge: 34
Win 7
Delphi 7 Profesional,Visual Basic
|
Verfasst: Mi 05.07.06 13:53
assarbad.net -> fastscan
der arbeitet sogar mit 256 Threads
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Mi 05.07.06 14:08
Aber eigentlich bringen so viele doch nix! So viele Prozessorkerne, wie man hat, so viele macht es ungefähr auch Sinn. Dass man das nicht im MainThread ablaufen lässt ist ja klar, warum. Aber je mehr Threads man hat, desto höher ist doch der Verwaltungsaufwand für Windows, desto mehr Zeit geht durch diese Organisation des Multitasking drauf und desto weniger bringen zusätzliche Threads, weils ja nicht wirklich gleichzeitig abläuft. Nur wenn man mehrere Kerne hat, dann läufts gleichzeitig ab und dann machen ein paar mehr Threads schon etwas mehr Sinn
Gruß alias5000
_________________ Programmers never die, they just GOSUB without RETURN
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 05.07.06 14:22
Moin!
alias5000 hat folgendes geschrieben: | | Aber eigentlich bringen so viele doch nix! So viele Prozessorkerne, wie man hat, so viele macht es ungefähr auch Sinn. |
Naja, grundsätzlich magst du Recht haben. Allerdings bringen hier mehrere Threads schon was, denn damit kannst du die Wartezeiten parallelisieren.
@ Highspeeder: Wenn Assarbad mit so vielen Threads arbeitet, wird er schon wissen, welche Umgebung und Systemkonfiguration dafür nötig ist.
Ich meinte aber eher den Ansatz mit den TCP-Connects auf Basis der Indy-TCP-Kompo. Einen entsprechenden Scanner macht man besser mit RawSockets und dazugehörigem Hintergrundwissen über die Internetprotokollfamilie -> deshalb der nmap-Hinweis.
[philosophie]Ich weiß nicht, warum Portscanner so einen unglaublichen Reiz ausüben, muss so ein "verboten-Flair" haben, in Richtung hacken, dabei kommt man sich dann vermutlich cool vor.  "Echte Hacker" würden wahrscheinliche lieber eine funktionierende Lösung nehmen, als sich mit sowas aufzuhalten, deshalb frage ich mich immer wieder, warum man sich ausgerechnet daran "üben" muss, statt eine sinnvolle Netzwerkapplikation zu programmieren - damit kann man genausoviel lernen, aber nervt andere weniger.[/philosophie]
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Mi 05.07.06 14:29
_________________ Programmers never die, they just GOSUB without RETURN
|
|
Highspeeder 
      
Beiträge: 34
Win 7
Delphi 7 Profesional,Visual Basic
|
Verfasst: Mi 05.07.06 14:45
Ja die Threads sollen die Geschwindigkeit erhöhen.
Immerhin kann es sein das man mal eine oder 2 Sekunden warten muß, bis eine Antwort vom Host kommt.
Und wenn ich alle Ports nachguggen will, dann sind das immerhin 65000 Stück oder so.
Ja..mit nem Scanner kann man anonyme Mailserver oder Proxys suchen..nur mal zum Beispiel (oder Trojaner).
Dann könnte man die Ergebnisse in einer Datenbank speichern.
Ich persönlich finde Nmap halt ätzend, weil das auf Kommandozeilenebene läuft.
Da geht gar nix mit automatisieren.
Mußt die Kommandos im Kopf haben und ellenlange Befehle eintippen.
Im übrigen will ich nicht nerven sondern was eigenes programmieren.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 05.07.06 15:11
Moin!
Highspeeder hat folgendes geschrieben: | | Im übrigen will ich nicht nerven sondern was eigenes programmieren. |
Schon klar, du willst einen Portscanner zu rein "theoretischen Zwecken" schreiben...
Fühl dich nicht angegriffen, es war nicht persönlich gemeint.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Highspeeder 
      
Beiträge: 34
Win 7
Delphi 7 Profesional,Visual Basic
|
Verfasst: Mi 05.07.06 15:15
nett lachen..aber ich hab vorher noch nie nen Thread programmiert.
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Mi 05.07.06 16:26
Ist dir klar, was ein Thread macht, weißt du, wie das Multitasking in Windows 95 aufwärts funktioniert, welche Probleme dabei drohen?
Ich hab mir das ganze mal theoretisch angeeignet und bin heilfroh drum, weil man sonst nicht weiß, was wirklich passiert. gDeswegen kann man Threads schlecht mit Try&error erlernen (finde ich).
Jetzt brauchste nur noch ne Quelle, hm...
Ich glaube zwar nicht, dass du hier ein ausführliches Tut findest, aber such mal in der EE, DP, Swissdelphicenter, dsdt.info und schließlich google. Hilft das nix und keiner bringt hier noch was, kann ich auf den Weg zur Bibliothek verweisen, dort findest du sicher ein Buch, das ausführlich in die Materie einführt (das war mein Weg)
Gruß alias5000
_________________ Programmers never die, they just GOSUB without RETURN
|
|
|