![]() |
Die Variable ServerIP herausfinden!(Scannen)
Chat Internetfähig machen!!!?!?!?!??!?!?!?!?[/color]
Mein Programm soll im Internet laufen, da ich keine feste IP habe benötige ich ein scanntool, das mir die ServerIP herausfindet, nur wie! Newbee sucht Hilfe! Dieser vereinfachte Code zeigt mein Problem!
Delphi-Quellcode:
Wenn nun die Verbindung versucht wird aufzubauen kommt eine Fehlermeldung, logisch und das Programm bleibt stehn! Wieverhindere ich diese Fehlermeldung, so das alle 255 Möglichkeiten ausprobiert werden und hinterher nur noch die richtigen ips in der Listbox stehen!
PROCEDURE SCAN;
VAR i:Integer; Begin For i:=0 to 255 do Begin Client.host:='192.168.2.'+inttostr(i); Client.open; If Client.socket.connected=true then Listbox1.items.add('Client.host'); Client.close; end; end; Habe schon mit Try und Except experimentier, hat aber den gleichen Effekt! Bitte um Hilfe! Thx [Edit=Sakura]Delphi-Tags eingefügt.[/Edit] |
Es gibt sicherlich bessere Möglichkeiten, aber versuchs mal hiermit:
Delphi-Quellcode:
PROCEDURE SCAN;
VAR i:Integer; Begin For i:=0 to 255 do Begin Client.host:='192.168.2.'+inttostr(i); Try Client.open; If Client.socket.connected=true then Listbox1.items.add('Client.host'); Client.close; except //irgentwas - Vielleicht ne Meldung end; end; end; |
Problem nit behoben
Das habe ich auch schon versucht, aber das Problem bleibt das gleiche!
Asynchronous socket error 10049 Das Problem is , das ich diese Fehlermeldung nicht umgehen kann! Ich müsste ihm irgendwie begreiflich machen, das er dann abbricht und die Schleife fortsetzt! Trotzdem vielen Dank! |
Mit welche Komponente arbeitest du denn hier, und auf welchem Port soll die Kommunikation erfolgen. (Dann könnte man das mal ausprobieren).
|
Port 25555
Ich arbeite mit Delphi 6 enterprise und den normalen Winsockets, also Serversocket und clientsocket! Zu einer IP, die das pro. geöffnet hat kann ich eine Verbindung herstellen, daher habe ich eine Fehleinstellung ausgeschlossen! Ich glaube das Problem ist, dass sich try und client.open nit vertrangen! Naja , bin dankbar für jede Hilfe! Thx schon mal |
Hi ATwardz,
ich hab mal ein bischen ausprobiert. In folgender procedure:
Delphi-Quellcode:
Wenn du den ErrorCode auf 0 setzt wird keine Exception ausgelöst. Du muß dann nur noch eine Variable setzen, und deren Wert in deiner Schleife abfangen, damit Sie unterbrochen wird.
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin ListBox2.Items.Add(ClientSocket1.Address); ErrorCode:=0; end; Oder du setzt die Variable in ClientSocket1Connect damit deine Schleife bei einer erfolgreichen Verbindung abbricht. Bei mir funktionierts :mrgreen: |
Es ist zum verrückt werden!
Vielen dank! Jetzt gehts!
Juchu , leider noch nit ganz! Es gibt jedoch noch ein Problem! Das Programm soll alle Falschen IP's ( nur zur Kontrolle in Listbox2 auflisten und die richtige in Listbox1); Das Problem liegt eindeutug daran, das der Befehl Client.open erst nach der Procedure ausgeführt wird! :cry: Die Schleife wird erst komplett ausgeführt , dann die Error Procedure und dann die Connect Procedure!Da Onconnect erst nach der Schleife ausgeführt wird und dort die Variable geändert wird, läuft die Schleife auf jedenfall bis zum ende! Und es wird die letzte IP in die Listbox geschrieben!
Delphi-Quellcode:
Ich habe auch schon versucht die For-Schleife durch eine While-Schleife zu erstzen, aber der Effekt ist der Gleiche!procedure TForm1.BT_tryClick(Sender: TObject); VAR i:Integer; Begin i:=103; While i<104 do Begin Client1.host:='192.168.2.'+inttostr(i); Try client1.open; If client1.Socket.Connected=true then Begin Listbox1.Items.Add(client1.Host); exit; end; finally beep; end; i:=i+1; end; end; procedure TForm1.Client1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin ErrorCode:=0; Listbox2.Items.Add(Client1.Host); end; Es ist zum verrückt werden, nun funktioniert der Scan aber ich kann die richtige IP nit rausfiltern! :freak: |
Versuchs mal hiermit
Delphi-Quellcode:
Wenn das auch nicht klappt, dann mach doch den Open mal über einen Timer, und werte die OnConnect und OnError Ereignisse aus.
Client1.Open
Application.ProcessMessages; <<<<<<<<<<<<<<<< if Client1.Socket.Connected then ... Hatte das vorhin mal in D6 ausprobiert. Ich such nochmal. PS: Das =True hinter Client1.Socket.Connected kannst du dir sparen, da Client1.Socket.Connected schon ein True oder False zurückliefert. |
Ich habe jetzt mal was Ausprobiert.
Hier mein Code:
Delphi-Quellcode:
Wenn du den Button1 benutzen willst, dann muß du die Auskommentierung unter OnError und OnConnect wieder rausnehmen.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Sockets, ExtCtrls, ScktComp, Buttons; type TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; ListBox2: TListBox; Timer1: TTimer; Label1: TLabel; Label2: TLabel; ClientSocket1: TClientSocket; BitBtn1: TBitBtn; procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure BitBtn1Click(Sender: TObject); private { Private-Deklarationen } public i: Integer; { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Timer1Timer(Sender: TObject); begin ClientSocket1.Address:='192.168.0.'+inttostr(i); Try ClientSocket1.Open; if ClientSocket1.Active then begin ListBox1.Items.Add(ClientSocket1.Address); ClientSocket1.Close; end else ListBox2.Items.Add(ClientSocket1.Address); finally ClientSocket1.Close; i:=i+1; if i=21 then timer1.Enabled:=False; end; end; procedure TForm1.Button1Click(Sender: TObject); begin i:=1; Timer1.Enabled:=true; end; procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin //ListBox2.Items.Add(ClientSocket1.Address); ErrorCode:=0; end; procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin //ListBox1.Items.Add(ClientSocket1.Address); //ClientSocket1.Close; end; procedure TForm1.BitBtn1Click(Sender: TObject); var i: Integer; begin ListBox1.Clear; ListBox2.Clear; For i:=1 to 20 do begin ClientSocket1.Address:='192.168.0.'+inttostr(i); Try ClientSocket1.Open; Application.ProcessMessages; if ClientSocket1.Socket.Connected then ListBox1.Items.Add(ClientSocket1.Address) else ListBox2.Items.Add(ClientSocket1.Address); ClientSocket1.Close; except beep; end; end; end; end. Aber mir ist dabei ein Phänomen aufgefallen: die Timer-Lösung funktioniert richtig (Gefällt mir aber nicht) die BitBtn-Lösung liefert erst ab dem 2. Klick die richtige IP-Adresse. Eigentlich müsste das schon beim 1. Klick so sein. Liegt warscheinlich daran, das beim Open nicht wirklich gewartet wird, bis die Verbindung aufgebaut ist. Und wenn das dann zu lange dauert, wird eine IP ausgegeben, die nicht stimmt, da die Schleife schon weiter ist. Also folgende Lösung sollte dann aber auch das Problem lösen. Du setzt eine Globale Booleanvariable 'test' auf False. Nach dem Open läßt du dann eine While-Schleife laufen, die auf ein test=True wartet. Im OnConnect und OnError setzt du die dann auf True. Dann geht das aufwärtzählen der IP nur weiter, wenn die Open-Procedure abgeschlossen ist. So oder so. Zur Sicherheit kannst du dann ja noch einen Timer mit einem Timeout von 30 Sek vor der While-Schleife starten, der auf jeden Fall Test auf True setzt. Probier das doch mal. |
Ahhhh bei mir geht weder die eine noch die andere Lösung!
Ich habe ein testprogramm mit nur diesen Procedure erstellt! Timer-Lösung! Listet mir alle Ip's bis auf die Letzte auf, aber alle nur in die Listbox2! BitBtn-Lösung! Listet mir alle Ip's auf jedoch ebenfalls nur ind die Listbox2! Mit F7 sieht man , das die onconnect Procedure nicht ausgeführt wird! Ich weiss nit woran es liegt, vielleicht ist mein delphi kaputt oder verarscht mich einfach nur!
Delphi-Quellcode:
Ich werde noch verrückt! :freak:unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, Buttons, StdCtrls, ExtCtrls; type TForm1 = class(TForm) ClientSocket1: TClientSocket; Timer1: TTimer; Button1: TButton; BitBtn1: TBitBtn; ListBox1: TListBox; ListBox2: TListBox; procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); procedure BitBtn1Click(Sender: TObject); private { Private declarations } public i:Integer; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin Form1.Caption:='Connected'; end; procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); begin Form1.Caption:='Disconnected'; end; procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin Errorcode:=0; end; procedure TForm1.Timer1Timer(Sender: TObject); begin ClientSocket1.Address:='192.168.0.'+inttostr(i); Try ClientSocket1.Open; if ClientSocket1.Socket.Connected then begin ListBox1.Items.Add(ClientSocket1.Host); ClientSocket1.Close; end else ListBox2.Items.Add(ClientSocket1.Address); finally ClientSocket1.Close; i:=i+1; if i=110 then timer1.Enabled:=False; end; end; procedure TForm1.Button1Click(Sender: TObject); begin i:=100; Timer1.Enabled:=true; end; procedure TForm1.BitBtn1Click(Sender: TObject); var i: Integer; begin ListBox1.Clear; ListBox2.Clear; For i:=100 to 110 do begin ClientSocket1.host:='192.168.0.'+inttostr(i); Try ClientSocket1.Open; Application.ProcessMessages; if ClientSocket1.Socket.Connected then ListBox1.Items.Add(ClientSocket1.Host) else ListBox2.Items.Add(ClientSocket1.Host); ClientSocket1.Close; except beep; end; end; end; end. |
Bevor ich mich jetzt dran mache:
wie lautet denn deine IP-Adresse auf der du das getestet? In deiner ersten Mail steht 192.168.2.x in deiner letzten steht 192.168.0.x; Hast du womöglich mit meiner IP getestet? Das bei der Timerlösung die letzte nicht mehr in Listbox2 auftaucht, ist logisch. Setzt mal das i:=i+1 hinter die if-abfrage, dann wird die letzt auch getestet. |
Oh bin ich blöd, ja die Variante ohne Timer funkst jetzt!
Bei der mit Timer, sagt er das er die adress nit ändern kann während der Socket aktiv ist, weil er client1.close nit annimmt bzw. weil er den timer nit abschaltet! [/delphi] procedure TForm1.Timer1Timer(Sender: TObject); begin Client1.host:='192.168.2.'+inttostr(i); Try Client1.Open; If Client1.Socket.Connected then Begin Listbox1.Items.Add(Client1.Host); client1.Close; end else Begin Listbox2.Items.Add(Client1.Host); end; finally Client1.Close; If i=105 then Timer1.Enabled:=false; i:=i+1; end; end; [delphi] Das ist aber eigentlich egal weil die andere Variante, die die schöner ist funktioniert und dafür bin ich sehr dankbar! Echt vielen Dank weil sonst wäre ich glaube ich nie dahinter gestiegen! :D Thx @wardz |
Ach ja ein Problem gibt es noch, was ich mir fast schon gedacht habe!
Da die IP ja x.x.x.x vier Stellen hat und ich also drei weitere Forschleifen davor geschaltet habe, wird der Pc überlastet. Er sagt mir das der Puffer voll ist Genau gesagt! Windows socket error:Ein Socketvorgang konnte nicht ausgeführt werden, da dem System Pufferspeicher fehlte oder eine Warteschlange voll war (10055), on API'connect' Wie kann ich nach einer bestimmten Zeit den Speicher wieder freigeben!
Delphi-Quellcode:
Oder kann ich vielleicht 4 verschieden Proceduren anlegen, weil ja nach dem schliessen der Procedure der speicher wieder freigegeben wird?
procedure TForm1.Button3Click(Sender: TObject);
var i,c,b,a: Integer; begin ListBox1.Clear; ListBox2.Clear; For a:=1 to 255 do Begin For b:=1 to 255 do Begin For c:=1 to 255 do Begin For i:=1 to 255 do begin Client1.host:='192.'+inttostr(b)+'.'+inttostr(c)+'.'+inttostr(i); Try Client1.Open; Application.ProcessMessages; if Client1.Socket.Connected then Begin ListBox1.Items.Add(Client1.Host); exit; end else //ListBox2.Items.Add(Client1.Host); Client1.Close; except beep; end; end; if Client1.Socket.Connected then Begin exit; end; end; end; end; end; Ich weiss das der scan bei mehr als 4 Millaren möglichkeiten vermutlich nie fertig wird aber ich wollte eine Eingrenzung später möglich machen! Die Fehlermeldung kommt auch schon bei einem Spektrum von 192.168.1.1 bis 192.168.3.1 also ja nur 765 Möglichkeiten! Gibs da vielleicht ne Möglichkeit? Danke! |
Was machst du denn damit? Für ein Chatprogramm schon etwas merkwürdig. Sieht mir eher wie ein Suchprog für offene Ports aus. Aber naja.
Du bist dir schon im Klaren, das wenn du die suche startest (im Internet), das du dann erstmal eine Kanne Kaffee kochen und dann auch trinken kannst, bis das fertig ist. :mrgreen: Aber gut, zurück zu deinem Problem. Ich schau mir das mal an. Mal sehen, was ich rauskriege. |
Mein Chatprogramm hat
Server-soll bei mir laufen Client-soll bei diversen nutzern laufen! Ip-scanner soll nun also meine IP für die Clients rausfinden, da ich ja keine static IP habe! Kanne Kaffe is gut, ich habe ausgerechtet, das ich rund ein dreiviertel jahr brauche um alle IP's zu testen! :? Naja ich weiss aber auch,das mein Provider unserem Router die IP's von 213.146.1.1 bis 213.146.255.255 vergibt,was den Scan ja auf 255*255=65025 reduziert, jedoch kommt die Speicherüberlastung schon nach ungefähr 500 gescannten IP's! Wenn ich das nu auf die Reihe bekomme, ist mein server immer erreichtbar Eine Andere Möglichkeit wäre mein in eine Website zu integrieren, jedoch weiss ich nit ob das so ohne Probleme geht, da ich bis jetzt nur einfache Programme integriert habe wie Taschenrechner oder Counter! Die sind ja nicht ständig aktiv, sondern werden von einem Betrachter der Website geöffnet! Noch ein grund ist das es vielleicht Konflikte mit dem Port geben könnte, aber wie gesagt habe mich noch nicht damit befasst! Danke im Vorraus! @wardz :coder: |
Ich denke in deinem Fall kannst du das nur über UDP realisieren.
UPD ist ein Verbindungsloses Protokoll. D.h. du schickts einfach an jede IP ein UDP-Packet, nix wildes nur irgendein zeichen. Wenn dein Server dann so ein Zeichen empfängt, dann kann er ja per TCP eine Verbingung aufbauen, die IP hast du ja dann. Nach Verbindungsaufbau hat der Client dann auch die Server-IP. Wär das ne Idee ? |
UDP
Ja egentlich schon aber dann muss ich auf die TCP Komponente
umsteigen oder? Wenn ja dann werde ich wohl das erstma in angriff nehmen und mein Programm umschreiben! Thx :coder: |
Oder geht das nit auch vielleicht wenn ich den Clientsocket nach jeder 255 for-schleife freisetze und dann neu erzeuge? Habe ich vesucht aber ich glaube der übernimmt dann den Fehlercode 0 nit!
Delphi-Quellcode:
Der schreit dann asynchron socket... aber das versteh ich nit!procedure TForm1.BitBtn1Click(Sender: TObject); var a,b: Integer; begin If client1.Active=false then Begin ListBox1.Clear; For b:=1 to 255 do Begin client1:=Tclientsocket.Create(self); client1.Close; client1.Port:=25555; client1.Socket. For a:=1 to 255 do begin Client1.host:='192.168.'+inttostr(b)+'.'+inttostr(a); Try Client1.Open; Application.ProcessMessages; if Client1.Socket.Connected then Begin ListBox1.Items.Add(Client1.Host); exit; end; client1.Close; except beep; end; end; end; end; end; Theoretisch müsste das doch geht, weiter der Speicher dann freigegeben wird wenn man das Objekt freisetzt oder? Danke @wardz |
Du folgendes erzeugt:
Code:
aber, wo ist das client1.free ? :?:
client1:=Tclientsocket.Create(self);
|
War vor dem Create vom Socket also:
Delphi-Quellcode:
Komisch is nur das der Fehler unregelmässig auftritt!procedure TForm1.BitBtn1Click(Sender: TObject); var a,b: Integer; begin If client1.Active=false then Begin ListBox1.Clear; For b:=1 to 255 do Begin client1.Free; client1:=Tclientsocket.Create(self); client1.Close; client1.Port:=25555; For a:=1 to 255 do begin Client1.host:='192.168.'+inttostr(b)+'.'+inttostr(a); Try Client1.Open; Application.ProcessMessages; if Client1.Socket.Connected then Begin ListBox1.Items.Add(Client1.Host); exit; end; client1.Close; except beep; end; end; end; end; end; Mi F7 habe ich mehr mals probiert und bin bis 255 durch gelaufen wenn ich es langsam gemacht habe, wenn ich F7 gedrückt hielt, hin er sicht ca nach 10 Ip's auf!? Vielleicht ist die Schleife zu schnell für das freigeben des Sockets? ??? |
Na, dann wirds wohl ein Problem mit dem Timing sein .
Wie hast du denn den BlockingMode gesetzt? Aber ich denke es ist müsig, so weiter zu machen. Denn selbst wenn du es schaffst, wie lange soll die Suche dauern ? Kannst du doch keinem User zumuten. Hat schon seinen Grund, das alle Internetchatprogramme sich bei einem festen Server anmelden. Am besten du nimmst eine andere Methode, deinen Clients die Server-IP mitzuteilen. Wie wärs denn mit DynDNS. Oder du legst die IP auf einem FTP ab. |
Es funktioniert!!!!!!!
Ich habs, es zwar eine etwas umständlich lösung aber sie funkst!
ca 65000 ips in 23 sekunden! Ich habe einfach das komlpette scann programm als eigenes Programm gescvhrieben, was sich bis 255 immer selber auf ruft es sei den die verbindung steht! Nicht gerade die ideals aber was solls, es funksts! :D :D :D :D :D Ich brauche dann zwar immer noch rund 7 tage bis ich alle IP's (4,3 Milliarden ) gescannt habe , aber aber da wie gesagt mein Server die beiden ersten stellen immer gleich vergibt, ist es eine akzeptale Lösung!
Delphi-Quellcode:
Die Datei IP muss dann nur noch im eigentlichen Programm eingegeben werden!procedure TForm1.FormCreate(Sender: TObject); Begin test:=true; ipscan; end; Procedure Tform1.ipscan; var a:Integer; ZAHL: string; begin memo2.Clear; memo2.Lines.LoadFromFile('IP.ip'); ZAHL:=memo2.Lines.Strings[0]; If strtoint(Zahl)<256 then Begin For a:=1 to 255 do begin Try Client1.host:='192.168.'+Zahl+'.'+inttostr(a); Client1.Open; Application.ProcessMessages; If client1.socket.connected=true then Begin memo2.Clear; memo2.Lines.Add(client1.Host); memo2.Lines.SaveToFile('Host.ip'); Form1.Visible:=true; client1.Close; test:=true; exit; end; except beep; end; client1.Close; end; memo2.Clear; memo2.Lines.Add(inttostr(strtoint(Zahl)+1)); memo2.Lines.SaveToFile('IP.ip'); test:=false; end else Begin memo2.Clear; memo2.Lines.Add('0'); memo2.Lines.SaveToFile('IP.ip'); test:=false; end; end; procedure TForm1.Client1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin Errorcode:=0; end; procedure TForm1.Timer1Timer(Sender: TObject); begin If Test=false then Begin winexec(pchar('Scanner.exe'), SW_hide); Form1.Close; end; end; Ich werde auch noch den Code für xxx.xxx.xxx.xxx hier zeigen aber der muss erst geschrieben werden! Vielen Dank nochman, weil ohne deine Hilfe wäre ich da wahrscheinlich nie drauf gekommen! Also danke! @wardz :chat: :freak: |
Ich halte deine Lösung zwar immer noch nicht für die richtige, zumindest für ein Chatprogramm, aber:
Statt WinExec solltest du ShellExecute benutzen, weil du dann auch Parameter mit übergeben kannst:
Delphi-Quellcode:
Die Paramenter wertest du dann in "programm.exe" beim OnCreate aus mit
ShellExecute(Handle,PChar('open'),PChar('programm.exe'),PChar('192.168.2.1'),nil,SW_SHOW);
Delphi-Quellcode:
Dann sparst du dir das umständliche Übergeben der IP mit einer Textdatei.
if ParamCount=2 then
IP:=ParamStr(1) //ParamStr(0) ist der Programmname else Application.Terminate; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:36 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