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
BeitragVerfasst: 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:
ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    Socket : TUdpSockUtil;
    procedure Recieve(Sender:TObject);
    procedure Error(Sender:TObject;Error:Integer);
  public
    { Public-Deklarationen }
  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
  //loool
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 22.07.08 16:06 
Moin!

user profile iconalmdudler777 hat folgendes geschrieben:
wie kann ich folgendes 'Statement' an den Server schicken?
z.B. so:
ausblenden 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:
user profile iconalmdudler777 hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm3.Recieve(Sender: TObject);
var RemoteAddr : in_addr; msg : string;
begin
  //loool
  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. :idea:

Ansonsten: Gamespy-Protokoll-Doku wälzen und verstehen (sorry, davon habe ich leider keine Ahnung). :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
almdudler777 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: 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.

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    Socket : TUdpSockUtil;
    procedure Recieve(Sender:TObject);
    procedure Error(Sender:TObject;Error:Integer);
  public
    { Public-Deklarationen }
  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
  //loool
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 22.07.08 21:40 
Moin!

user profile iconalmdudler777 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) :nixweiss:

Viel Spaß beim Entziffern. :D

cu
Narses
Einloggen, um Attachments anzusehen!
_________________
There are 10 types of people - those who understand binary and those who don´t.
almdudler777 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: Di 22.07.08 23:29 
user profile iconNarses 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) :nixweiss:

Viel Spaß beim Entziffern. :D



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...

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: 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?

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    rList : TStringList;
    Socket : TUdpSockUtil;
    procedure Recieve(Sender:TObject);
    procedure Error(Sender:TObject;Error:Integer);
    function searchPort(pport:integer) : integer;
  public
    { Public-Deklarationen }
  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;
    //if ((i mod 16) = 0) then
      //Result := Result +#13#10;
  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);
  //Memo1.Lines.Add('Anfrage gesendet');
end;

procedure TForm3.Error(Sender: TObject; Error: Integer);
begin
  Memo1.Lines.Add(IntToStr(Error));
end;

end.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 27.07.08 00:53 
Moin!

user profile iconalmdudler777 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 :idea:)

user profile iconalmdudler777 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. :nixweiss:

user profile iconalmdudler777 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 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: So 27.07.08 14:41 
user profile iconNarses 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 :idea:)

user profile iconalmdudler777 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 27.07.08 23:21 
Moin!

user profile iconalmdudler777 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? :nixweiss: 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. :idea:

user profile iconalmdudler777 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.

user profile iconalmdudler777 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. :nixweiss:

user profile iconalmdudler777 hat folgendes geschrieben:
Wenn ich es hier im Forum suche findet man nur Threads die irgendwie mit der UpdSockUtil zu tun haben.
Hä? :gruebel:

user profile iconalmdudler777 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 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: Di 29.07.08 21:48 
Hi

user profile iconNarses hat folgendes geschrieben:
Moin!

1.) Mal Klartext: kennst du dich gut mit Threads in Delphi/WinAPI aus? :nixweiss: 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. :idea:

1.)
user profile iconalmdudler777 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 30.07.08 00:01 
Moin!

user profile iconalmdudler777 hat folgendes geschrieben:
Das ich das nun auch mit der UDPSockutil ereignisorientiert lösen kann ist klar...
Das klang bisher aber nicht so. ;)

user profile iconalmdudler777 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? :)

user profile iconalmdudler777 hat folgendes geschrieben:
das läuft ja eben wieder nicht ereignisorientiert :)
Sofern du sie meintest: die kann doch asynchron pingen. :nixweiss:

user profile iconalmdudler777 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. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
almdudler777 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: Mi 30.07.08 14:19 
user profile iconNarses 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. :nixweiss:

4.) Such halt nach einem UDP-Tutorial für die Indy-Komponenten, da sollte das gehen. :idea:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 30.07.08 23:05 
Moin!

user profile iconalmdudler777 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... :?

user profile iconalmdudler777 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. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
almdudler777 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: Do 31.07.08 13:35 
user profile iconNarses hat folgendes geschrieben:
Moin!

user profile iconalmdudler777 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 Threadstarter
Hält's aus hier
Beiträge: 12

Win XP Prof., Win7 Professional
Delphi 2010 Prof., MS Visual Studio 2010 Prof., Lazarus, MonoDevelop, Netbeans
BeitragVerfasst: Di 05.08.08 00:01 
moin,


also es klappt soweit sehr gut nur gibt es ein nicht ganz unerhebliches Problem :shock:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 07.08.08 01:12 
Moin!

user profile iconalmdudler777 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. :)

user profile iconalmdudler777 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. :nixweiss: 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... :lupe: 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:
ausblenden volle Höhe Delphi-Quelltext
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
  // Portmapping-Phase und Port schon belegt? -> nächsten nehmen
  if ( (PortMapTimeout.Enabled) and (Error = WSAEADDRINUSE) ) then begin
    LogIt('Port '+IntToStr(UDPSocket.LocalPort)+' bereits belegt!');
    if (UDPSocket.LocalPort < 41000then begin
      UDPSocket.Close; // Achtung! Nicht hier wieder öffnen, wird mit AV bestraft!
      PostMessage(Handle,CM_NEXTPORT,UDPSocket.LocalPort +1,0); // per Message dereferenzieren
    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// nächster Port
  UDPSocket.Open; // und nächster Versuch
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.