Autor |
Beitrag |
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Di 22.07.08 12:18
Hallo Leute,
ich hätte da mal eine Frage.
Und zwar benutze ich die TUdpSockUtil bzw. will sie benutzen.
Hintergrund: Mein Programm soll serverstats von Gameservern abfragen und das geht nur über ne udp verbindung.
(Gamespy2-Protocoll)
Wenn ich den server mit sendtext abfrage, bekomme ich auch bereits ohne Probleme eine Antwort... das Problem ist nur die Antwort ist noch vom Gamespy1 Protokoll was allerdings nicht mehr funktioniert und nach 2000bytes oder so abbricht...
Bei mir harperts wahrscheinlich wieder daran das ich ein Anfänger bin... wie kann ich folgendes 'Statement'
an den Server schicken?
\xFE\xFD\x00PiNG\xFF\x00\x00
Bis jetzt realisiere ich das über ein PHP Script dessen ausgabe ich in mein Programm lese, das ist aber nicht wirklich Threadsafe
Folgendes Testprogramm habe ich zur Veranschaulichung geschrieben... das \\Status\\ ist einfach nur nen string aus dem alten Protokoll... achja Sendtext bekommt auch mit nem leerstring immer die gleiche Antwort... also werd ich es über SendBuf machen müssen nur wie? xD
Danke im Voraus,
Daniel
Testprogramm:
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:
| unit Unit3;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,UdpSockUtil, StdCtrls,Winsock;
type TForm3 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private Socket : TUdpSockUtil; procedure Recieve(Sender:TObject); procedure Error(Sender:TObject;Error:Integer); public end;
var Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject); begin Socket := TUdpSockUtil.Create(Form3); Socket.LocalPort := 10000; Socket.Listen := true; Socket.OnReceive := Recieve; Socket.OnError := Error; Socket.RemoteHost := '194.153.116.125'; Socket.RemotePort := 1717; end;
procedure TForm3.FormDestroy(Sender: TObject); begin Socket.Close; end;
procedure TForm3.Recieve(Sender: TObject); var RemoteAddr : in_addr; msg : string; begin Memo1.Clear; msg := Socket.ReceiveText(RemoteAddr); Memo1.Lines.Add(msg); end;
procedure TForm3.Button1Click(Sender: TObject); var query : shortstring; begin Socket.Open; Socket.SendText('\\status\\'); end;
procedure TForm3.Error(Sender: TObject; Error: Integer); begin Memo1.Lines.Add(IntToStr(Error)); end;
end. |
Zuletzt bearbeitet von almdudler777 am Sa 26.07.08 14:56, insgesamt 1-mal bearbeitet
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.07.08 16:06
Moin!
almdudler777 hat folgendes geschrieben: | wie kann ich folgendes 'Statement' an den Server schicken? |
z.B. so:
Delphi-Quelltext 1:
| Socket.SendText(#$FE#$FD#$00+'PiNG'+#$FF#$00#$00); |
Der Server wird aber vermutlich auch eine binäre Anwort liefern, deshalb ist das hier:
almdudler777 hat folgendes geschrieben: | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm3.Recieve(Sender: TObject); var RemoteAddr : in_addr; msg : string; begin Memo1.Clear; msg := Socket.ReceiveText(RemoteAddr); Memo1.Lines.Add(msg); end; | |
nicht geeignet, die Antwort brauchbar auszugeben. So solltest erstmal die erhaltene Antwort in Hex umwandeln und dann erst ausgeben, sonst werden die Steuerzeichen verschluckt.
Ansonsten: Gamespy-Protokoll-Doku wälzen und verstehen (sorry, davon habe ich leider keine Ahnung).
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Di 22.07.08 20:11
Hi,
*g* also ich versteh nur Bahnhof... also das 'Statement' ^^ habe ich jetz so verschickt... auf die Abfrage von Socket.ReceiveLength() gibt er zurück, das er über 600 zeichen hat. Aber ReceiveText ist leer.
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:
| unit Unit3;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,UdpSockUtil, StdCtrls,Winsock;
type TForm3 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private Socket : TUdpSockUtil; procedure Recieve(Sender:TObject); procedure Error(Sender:TObject;Error:Integer); public end;
var Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject); begin Socket := TUdpSockUtil.Create(Form3); Socket.LocalPort := 10000; Socket.Listen := true; Socket.OnReceive := Recieve; Socket.OnError := Error; Socket.RemoteHost := '77.87.189.185'; Socket.RemotePort := 1717; end;
procedure TForm3.FormDestroy(Sender: TObject); begin Socket.Close; end;
procedure TForm3.Recieve(Sender: TObject); var RemoteAddr : in_addr; msg,buf : PAnsiChar; begin Memo1.Clear; Socket.ReceiveBuf(buf,2,RemoteAddr); BinToHex(buf,msg,length(buf)); Memo1.Lines.Add(msg); end;
procedure TForm3.Button1Click(Sender: TObject); var query : shortstring; begin Socket.Open; Socket.SendText(#$FE#$FD#$00+'PiNG'+#$FF#$00#$00); end;
procedure TForm3.Error(Sender: TObject; Error: Integer); begin Memo1.Lines.Add(IntToStr(Error)); end;
end. |
außerdem steht in meinem Memo nun die 10040 was denke ich mal nen WSA Error ist und der bedeutet anscheinend Nachricht zu lang
Ist bintohex überhaupt das was du meintest was ich mit der Rückgabe machen soll?
Zum Thema Gamespy Doku habe ich diese Seite gefunden:
www.int64.org/docs/g...tocols/gamespy2.html
ist aber schon lange nicht mehr aktuell, da dieser Query nicht mehr unterstützt wird und der neue GS3 Query geht bei Americas Army auch noch nicht
So long... wie gesagt totaler Anfänger....
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.07.08 21:40
Moin!
almdudler777 hat folgendes geschrieben: | also ich versteh nur Bahnhof... |
Ich merk das schon...
Hier mal mein Test-Projekt, der Server antwortet auch irgendwas - was, keine Ahnung, ich kenne das Protokoll nicht (und werde es auch nicht kennenlernen, nur so nebenbei)
Viel Spaß beim Entziffern.
cu
Narses
Einloggen, um Attachments anzusehen!
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Di 22.07.08 23:29
Narses hat folgendes geschrieben: | Moin!
Hier mal mein Test-Projekt, der Server antwortet auch irgendwas - was, keine Ahnung, ich kenne das Protokoll nicht (und werde es auch nicht kennenlernen, nur so nebenbei)
Viel Spaß beim Entziffern.
|
ahhhh MERCI - Fettes Danke damit kann man doch schon was anfangen, denn so ähnlich steht es auch auf der HP vom GS Protokoll....
ich gehe einfach mal davon aus, das PHP das bis jetzt immer schon automatisch quasi 'übersetzt' hat...
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| <?php $fp = fsockopen("udp://89.202.196.115",1717,$errnr,$error,2); socket_set_timeout($fp, 2); stream_set_timeout($fp, 2); fwrite($fp,"\xFE\xFD\x00PiNG\xFF\x00\x00"); $serveranswer = fread($fp,2000); echo $serveranswer = substr($serveranswer, 5); ?> fclose($fp); |
danke dir, ich werde mich mal ans Übersetzen machen, gehe aber davon aus, dass alles funktionieren wird von daher => Thread erledigt
PS: und ich sehe schon in punkto sockets lese ich besser noch nen paar Sachen ^^
MfG Daniel
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Sa 26.07.08 14:10
Moin,
also nochmal danke das Übersetzen hat soweit alles geklappt, und ich habe auch alles in der Form wie ich es zur weiteren Verarbeitung benötige.
Da meine Anwendung die Scans allerdings in Threads ausführt, brauche ich immer nen anderen localport. Da habe ich mir gedacht ok ab einem Startpunkt (zb. 10000) an aufwärts probieren und ne lücke suchen... nur das klappt irgendwie nicht ^^
Gibts ne elegante Lösung dafür? oder muss ich da in die TUdpSockUtil klasse direkt eingreifen?
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:
| unit Unit3;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,UdpSockUtil, StdCtrls,Winsock,functions;
type TForm3 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private rList : TStringList; Socket : TUdpSockUtil; procedure Recieve(Sender:TObject); procedure Error(Sender:TObject;Error:Integer); function searchPort(pport:integer) : integer; public end;
var Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject); var char : PChar; Port : integer; begin Socket := TUdpSockUtil.Create(Form3); Port := searchPort(10000); showmessage(IntToStr(port)); Socket.LocalPort := Port; Socket.OnReceive := Recieve; Socket.OnError := Error; Socket.RemoteHost := '85.25.150.117'; Socket.RemotePort := 1725; Memo1.Clear; rList := TStringList.Create; Socket.Listen := true; end;
function TForm3.searchPort(pPort: Integer) : integer; var port : integer; Socket : TUdpSockUtil; begin Socket := TUdpSockUtil.Create(nil); port := pPort; try socket.LocalPort := port; Socket.Open; except port := searchPort(port + 1); socket.Free; end; Socket.Free; result := port; end;
function HexDump(const S: String): String; var i: Integer; buf,buf2 : string; begin Result := ''; for i := 1 to Length(S) do begin Result := Result +IntToHex(Ord(S[i]),2)+#32; end; end;
function HexStrToStr(s: string) : string; var s2 : string; begin while s <> '' do begin if Pos(' ', s) <> 0 then begin s2 := Copy(s, 1, Pos(' ', s)-1); s := Copy(s, Length(s2)+2, MaxInt); end else begin s2 := s; s := ''; end;
if(StrToInt('$'+s2) = $00)Then Result := Result + '$00' else Result := Result + Chr(StrToInt('$' + s2)); end; end;
procedure TForm3.FormDestroy(Sender: TObject); begin Socket.Close; end;
procedure TForm3.Recieve(Sender: TObject); var IP: in_addr; Msg: String; arr : TSTringdynarray; i,z : integer; varname,varvalue : string; begin Msg := Socket.ReceiveText(IP); Memo1.Lines.Add(HexStrToStr(HexDump(Msg))); Memo1.Text := Copy(Memo1.Text,Pos('PiNG',Memo1.Text)+4,length(Memo1.Text)); arr := Explode('$00',Memo1.Text); z := 0; for I := 0 to High(arr) div 2 do begin varname := arr[z]; inc(z); varvalue := arr[z]; if (varname <> '') AND (varvalue <> '') then Form3.rList.Add(varname +'='+varvalue); inc(z); end; Memo1.Text := rList.Text; end;
procedure TForm3.Button1Click(Sender: TObject); var query : shortstring; begin Socket.SendText(#$FE#$FD#$00+'PiNG'+#$FF#$00#$00); end;
procedure TForm3.Error(Sender: TObject; Error: Integer); begin Memo1.Lines.Add(IntToStr(Error)); end;
end. |
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 27.07.08 00:53
Moin!
almdudler777 hat folgendes geschrieben: | Da meine Anwendung die Scans allerdings in Threads ausführt, |
Aha, allerdings:
a) enthält dein letzter Code keinen (weiteren) Thread, und
b) ist der TUdpSockUtil für ereignisorientierte Anwendungen entwickelt (man kann ihn zwar in Threads verwenden, aber da arbeitet man besser mit blocking-socket-calls )
almdudler777 hat folgendes geschrieben: | brauche ich immer nen anderen localport. Da habe ich mir gedacht ok ab einem Startpunkt (zb. 10000) an aufwärts probieren und ne lücke suchen... |
Globale Variable nehmen und bei jedem neuen Socket hochzählen, fertig.
almdudler777 hat folgendes geschrieben: | nur das klappt irgendwie nicht ^^ |
Klar klappt das nicht, da du nicht ereignisorientiert rangehst.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: So 27.07.08 14:41
Narses hat folgendes geschrieben: |
Aha, allerdings:
a) enthält dein letzter Code keinen (weiteren) Thread, und
b) ist der TUdpSockUtil für ereignisorientierte Anwendungen entwickelt (man kann ihn zwar in Threads verwenden, aber da arbeitet man besser mit blocking-socket-calls )
almdudler777 hat folgendes geschrieben: | nur das klappt irgendwie nicht ^^ | Klar klappt das nicht, da du nicht ereignisorientiert rangehst.
cu
Narses |
a) völlig richtig den Code habe ich neu geschrieben, um das übersetzten und rumprobieren nicht im eigentlichen Program machen zu müssen
b) das problem ist wie gesagt, dass ich noch nicht wirklich was in dem bereich gemacht habe und dank des extrem tollen Unterrichts in der Oberstufe bisher auch nicht wirklich etwas nützliches in Delphi gelernt habe. Was sind blocking-socket-calls? und kann ich sie mit Turbo Delphi benutzen? Wenn ich es hier im Forum suche findet man nur Threads die irgendwie mit der UpdSockUtil zu tun haben.
Wie viel Aufwand wäre es deine Unit in einem Thread zu benutzen?
MFG Daniel
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 27.07.08 23:21
Moin!
almdudler777 hat folgendes geschrieben: | dass ich noch nicht wirklich was in dem bereich gemacht habe und dank des extrem tollen Unterrichts in der Oberstufe bisher auch nicht wirklich etwas nützliches in Delphi gelernt habe. |
Mal Klartext: kennst du dich gut mit Threads in Delphi/WinAPI aus? Wenn nicht, dann lass den Thread-Ansatz besser, das geht auch ereignisorientiert: mach halt so viele UdpSockUtils auf, wie du gleichzeitig verwenden möchtest und lege die Ereignishandler zusammen, über den Sender-Parameter kannst du herausbekommen, welcher Socket geklingelt hat.
almdudler777 hat folgendes geschrieben: | Was sind blocking-socket-calls? |
Du kannst viele WinAPI-Funktionen synchron (auch blocking genannt) oder asynchron (eben "non-blocking) verwenden. Im ersteren Fall wartet dein Programm, bis der Funktionsaufruf komplett beendet ist, im zweiten Fall liefert die Funktion sofort eine Information, ob der Auftrag angenommen wurde (oder nicht) und meldet später über ein Ereignis (oder Callback), dass die Operation abgeschlossen ist.
almdudler777 hat folgendes geschrieben: | und kann ich sie mit Turbo Delphi benutzen? |
Das hängt nicht von der Delphi-Version ab, sondern von deinem Willen und der "Eignung" der entsprechenden Komponente. btw: der TUdpSockUtil arbeitet nur ereignisorientiert, also non-blocking oder auch asynchron.
almdudler777 hat folgendes geschrieben: | Wenn ich es hier im Forum suche findet man nur Threads die irgendwie mit der UpdSockUtil zu tun haben. |
Hä?
almdudler777 hat folgendes geschrieben: | Wie viel Aufwand wäre es deine Unit in einem Thread zu benutzen? |
Wozu? Für Threads ist die Kompo nicht gemacht, dafür solltest du dann besser eine andere nehmen. Probier´s halt mal ereignisorientiert aus, schadet doch nix.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Di 29.07.08 21:48
Hi
Narses hat folgendes geschrieben: | Moin!
1.) Mal Klartext: kennst du dich gut mit Threads in Delphi/WinAPI aus? Wenn nicht, dann lass den Thread-Ansatz besser, das geht auch ereignisorientiert: mach halt so viele UdpSockUtils auf, wie du gleichzeitig verwenden möchtest und lege die Ereignishandler zusammen, über den Sender-Parameter kannst du herausbekommen, welcher Socket geklingelt hat.
1.) almdudler777 hat folgendes geschrieben: | Wie viel Aufwand wäre es deine Unit in einem Thread zu benutzen? | Wozu? Für Threads ist die Kompo nicht gemacht, dafür solltest du dann besser eine andere nehmen. Probier´s halt mal ereignisorientiert aus, schadet doch nix.
cu
Narses |
Moinsen,
also da du ja schon so schön mit dem Klartext angefangen hast:
1.) Also Threads habe ich hier nen Tutorial liegen, aber nur notdürftig durchgelesen. Allgemein muss ich meine Erfahrung und mein Können in Delphi als Anfänger beschreiben. Wie gesagt, das meiste habe ich mir selbst beigebracht (im Stil von learning by doing ^^). Auf Delphi gekommen bin ich über den Informatikunterricht, welcher eher Mangelhaft war.
2.) Die Threads habe eigentlich nur aus folgendem Grund in mein Programm eingebaut:
Das Programm hat eine DB mit einer Liste von favoriten Gameserver. Startet man nun das Programm, dann lädt es im Oncreate direkt alle Server. (Hätte hier auch nen Splash machen können von wegen Programm lädt, oder sowas) Am Anfang war das auch nicht schlimm, dass das Formular erst nach ein paar Sekunden zu sehen war. Mit der neuen Version an der ich arbeite kommen allerdings viele Funktionen hinzu, welche man unabhängig von den favoriten Nutzen kann. Daher sollten die eben ab jetzt 'asynchron' im stillen Hintergrund geladen werden.
Das ich das nun auch mit der UDPSockutil ereignisorientiert lösen kann ist klar... nur ich brauche dazu auch noch nen Ping vom Server... und ich habe da ne Unit (lass mich raten könnte auch deine sein oder?!=>PingDemo ICMP) das läuft ja eben wieder nicht ereignisorientiert
Wie gesagt, bin für jede Kritik und Hilfe an dem Problem dankbar!
Merci, Daniel
EDIT: hast du nen Link zu einem geeigneten Tutorial für die Blocking socket calls? nur für den Fall das man den Ping nicht anders untergebracht bekommt ^^
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 30.07.08 00:01
Moin!
almdudler777 hat folgendes geschrieben: | Das ich das nun auch mit der UDPSockutil ereignisorientiert lösen kann ist klar... |
Das klang bisher aber nicht so.
almdudler777 hat folgendes geschrieben: | nur ich brauche dazu auch noch nen Ping vom Server... und ich habe da ne Unit (lass mich raten könnte auch deine sein oder?!=>PingDemo ICMP) |
Meinst du diese hier?
almdudler777 hat folgendes geschrieben: | das läuft ja eben wieder nicht ereignisorientiert |
Sofern du sie meintest: die kann doch asynchron pingen.
almdudler777 hat folgendes geschrieben: | hast du nen Link zu einem geeigneten Tutorial für die Blocking socket calls? |
Such halt nach einem UDP-Tutorial für die Indy-Komponenten, da sollte das gehen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Mi 30.07.08 14:19
Narses hat folgendes geschrieben: | Moin!
1.) Das klang bisher aber nicht so.
2.) Meinst du diese hier?
3.) Sofern du sie meintest: die kann doch asynchron pingen.
4.) Such halt nach einem UDP-Tutorial für die Indy-Komponenten, da sollte das gehen.
cu
Narses |
Moin!
1.) Na, ich musste ja erstmal die Fachbegriffe nachgooglen, die kenn ich ja nicht. Mal ganz ehrlich ich bin eh froh das ich weiß was das Formular, was die Anwendung ist ^^. Das ist vielen aus meinem Kurs bis heute nicht klar. Was allerdings dieses 'ereignisorientiert' ist, wusste ich ohne den Begriff zu kennen, da wir mit einer mehr oder weniger tollen Klasse, vom Ministerium vorgegeben, bereits ein wenig mit Internetsachen zu tun hatten. (auf Basis der TCustomSockets die bei Delphi mit drin sind).
2.) völlig korrekt, die meine ich ^^. Daraus habe ich mir quasi auch das Threadgerüst abgeschaut... mehr oder weniger gut weil es erst nicht funktioniert hat.
3.) ja keine Frage, ich denke du hattest sie ja geschrieben um den Unterschied zwischen nem Ping zur Laufzeit und nem Ping innem Thread zu zeigen. Das Problem ist nur, wenn ich nun die Unit benutze und nen Ping asynchron ausführe muss der nachher irgendwie sein Item in einem TListView finden obwohl das eigentlich auch das kleinere Übel ist.
4.) => Turbo Delphi wie gesagt ^^ Obwohl ich hier mal nen Thema von nem User gefunden hatte der weiß wie man die Sperre der Explorer Version umgehen kann... vllt. such ich mir den nochmal raus...
MFG Daniel
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 30.07.08 23:05
Moin!
almdudler777 hat folgendes geschrieben: | da wir mit einer mehr oder weniger tollen Klasse, vom Ministerium vorgegeben, bereits ein wenig mit Internetsachen zu tun hatten. (auf Basis der TCustomSockets die bei Delphi mit drin sind). |
Das Kultusministerium soll Delphi-Komponenten vorgeben? Glaub´ ich kaum, klingt viel eher nach einer "guten" Lehrerausrede, warum mal wieder "komische" Sachen in der Schule verwendet werden...
almdudler777 hat folgendes geschrieben: | Das Problem ist nur, wenn ich nun die Unit benutze und nen Ping asynchron ausführe muss der nachher irgendwie sein Item in einem TListView finden |
Kein Problem: gib dem asynchronen Ping bei der RefID einfach eine Referenz auf das TListItem mit, dann hast du im Callback-Handler den Bezug.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Do 31.07.08 13:35
Narses hat folgendes geschrieben: | Moin!
almdudler777 hat folgendes geschrieben: | da wir mit einer mehr oder weniger tollen Klasse, vom Ministerium vorgegeben, bereits ein wenig mit Internetsachen zu tun hatten. (auf Basis der TCustomSockets die bei Delphi mit drin sind). | Das Kultusministerium soll Delphi-Komponenten vorgeben? Glaub´ ich kaum, klingt viel eher nach einer "guten" Lehrerausrede, warum mal wieder "komische" Sachen in der Schule verwendet werden...
cu
Narses |
Kann gut sein. Fakt ist im Lehrplan war alles auf eine mSuM klasse ausgelegt. Sprich hübsch alles eingedeutscht und blos nix selber machen von wegen Canvas als eigene Klasse mit dem Namen Buntstift und so.
Ziemlicher Unfug der mir nicht wirklich geholfen hat Delphi zu verstehen ^^
Das geilste war eben der Abschnitt zur Netzwerkentwicklung... andauernd abgeschmiert. Da konnte man noch so sauber arbeiten... daher muss ich jetzt ja mal alles selbst angucken...
Aber ich danke dir, werde das mit dem Übergeben der Referenz auf das Item ausprobieren.
|
|
almdudler777
Hält's aus hier
Beiträge: 12
Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
|
Verfasst: Di 05.08.08 00:01
moin,
also es klappt soweit sehr gut nur gibt es ein nicht ganz unerhebliches Problem
Wenn der Server mal nicht erreichbar sein sollte, sprich WSA Error 10054 auftritt, dann bricht das Program ab...
Was kann man da machen? Ich vermute mal, man muss was in dem onError event machen nur was??
EDIT:
Das Problem mit dem Verschwinden der Server wenn sie offline sind habe ich gelöst... läuft soweit... muss nur noch den ganzen unnötigen Code raussäubern den ich für die Threads mal angelegt hatte.
Danke schonmal...
PS: gib mir doch mal nen tipp, wie man auch das mit den Ports elegant lösen könnte ^^ ich habe es nun über ein Array gemacht, das alle Ports, welche gerade benutzt werden, darstellt und halt vom typ boolean ist... jedes mal wenn der Socket geschlossen wird, dann wird auch der Port wieder 'freigegeben'. Aber es könnte ja sein, das von anderen Anwendungen Ports im Bereich von 30000 bis 31000 benutzt werden..
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 07.08.08 01:12
Moin!
almdudler777 hat folgendes geschrieben: | ich habe es nun über ein Array gemacht, das alle Ports, welche gerade benutzt werden, darstellt und halt vom typ boolean ist... jedes mal wenn der Socket geschlossen wird, dann wird auch der Port wieder 'freigegeben'. |
Das ist doch schonmal ein ziemlich guter Ansatz.
almdudler777 hat folgendes geschrieben: | Aber es könnte ja sein, das von anderen Anwendungen Ports im Bereich von 30000 bis 31000 benutzt werden.. |
Dagegen kann man grundsätzlich nichts unternehmen - wenn eine andere Anwendung den gewünschten Port schon belegt hat, dann hast du einfach verloren. Wenn du keinen großen Aufwand treiben willst, dann lass es so.
Wenn nicht: beim Versuch den Port zu öffnen, kriegst du eine entsprechende Meldung über OnError des Sockets. Hier musst du nun den nächsten Port auswählen und einen weiteren Versuch starten. Timeout für einen generellen Fehler nicht vergessen. Hm... ah, da ist es ja; mal ein Snippet aus einem älteren Projekt, wo ich das auch so machen musste, weil der Client auf dem Citrix-Server mehrfach gestartet wird:
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:
| procedure TForm1.UDPSocketError(Sender: TObject; Error: Integer); begin if ( (PortMapTimeout.Enabled) and (Error = WSAEADDRINUSE) ) then begin LogIt('Port '+IntToStr(UDPSocket.LocalPort)+' bereits belegt!'); if (UDPSocket.LocalPort < 41000) then begin UDPSocket.Close; PostMessage(Handle,CM_NEXTPORT,UDPSocket.LocalPort +1,0); end else begin LogIt('Local-Portrange überschritten!'); UDPSocket.LocalPort := 0; if (PortMapTimeout.Enabled) then UDPSocketWriteReady(Self); end; end else LogIt('UDP-Fehler: '+IntToStr(Error)); end;
procedure TForm1.CMNextPort(var Msg: TMessage); begin UDPSocket.LocalPort := UDPSocket.LocalPort +1; UDPSocket.Open; end;
procedure TForm1.PortMapTimeoutTimer(Sender: TObject); begin PortMapTimeout.Enabled := FALSE; LogIt('PortMap-Timeout!'); UDPSocket.LocalPort := 0; LogIt('Server: '+UDPSocket.RemoteHost+':'+IntToStr(UDPSocket.LocalPort)); CreateMessages; UDPSocket.SendText(Session.LogonMessage); end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
|