AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Hi,
ich denke Du must noch in Delphi unter "Tools\Optionen" den Bibliotheks-/Suchpfad setzen. Greetz Data |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Ne die Datei gibt es ja nicht bei mir auf dem Computer, habe ja danach gesucht.
Mein Projekt scheint aber noch zu funktionieren. Muste eigentlich nichts umstellen. Hoffe das ich das jetzt richtig installiert habe. Danke für deine Hilfe. Werde mal schauen wie weit ich komme... {Edit} Der Client friert dennoch ein :(, zum ko....{/Edit} {Edit} Wenn ich am Client das CS rausnehme kein Problem, irgend wo habe ich noch ein kleine Problem, naja....{/Edit} Mfg |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Hi Jackie,
dann poste nochmal Deinen jetzt aktuellen Code, Indy arbeitet übrings mit Blocking-Sockets, deshalb solltest Du Deinen "Client-Code" in einen Thread auslagern oder zumindest ein TIdAntiFreeze auf Deine Main-Form ziehen und die Eigenschaft "ApplicationHasPriority" auf true setzen. Greetz Data |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
hi,
ok wenn das nicht zu viel ist, mache ich das gerne. Ist alles im Thread :D Client Send
Delphi-Quellcode:
Client Execute
if not fclient.Connected then exit;
// fcs.Enter; try try fClient.WriteLn(ACmd.SendFrames); except end; finally // fcs.Leave; end;
Delphi-Quellcode:
fClient := TIdTCPClient.Create(nil);
fClient.ReadTimeout := 500; fClient.Host := fHost; fClient.Port := FPort; while not Terminated do begin //Prüfen ob Client Online if not fClient.Connected then begin try fClient.Connect(500); except //beep; end; end; //Ping senden (* if fClient.Connected then begin cmd := TCommandHandling.Create(CMDPing); try fCS.Enter; try fClient.WriteLn(cmd.SendFrames); msg := ''; msg := fClient.ReadLn; finally fCS.Leave; end; if msg = '' then fClient.Disconnect; except fClient.Disconnect; end; end; *) //Text empfangen if fClient.Connected then begin // fCS.Enter; try try IsTimeout := true; msg := fClient.ReadLn; IsTimeout := false; except //Timeout IsTimeout := True; end; if not IsTimeout then begin cmd := TCommandHandling.Create(CMDNone); try cmd.SetFrames(msg); try if Assigned(fOnRead) then fOnRead(cmd); except //Fehler in OnRead abfangen end; finally FreeAndNil(cmd); end; end; finally // fCS.Leave; end; end; sleep(100); end; |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
So nach dem ich jetzt schon den ganzen Tag am test bin und einfach nicht weiter weis.... Möchte ich das ganze mal beschreiben, vielleicht mach ich im Ansatz was falsch.
Ziel des Projektes ist es ein einfachen Server / Client zubekommen der Text über das Netzwerk sendet, später noch mit SSL. Die Clients müssen überwacht werden und sobald eine Verbindung nicht stimmt, muss der Server die Verbindung trennen und der client die Verbindung neu aufbauen. Der Server / TIdTCPServer. - Der Server läuft in einem Thread. - Im Execute vom Thread werden die Vars erstellt und eine While not Terminated Schleife mit sleep(100). - Im OnExecute vom Server werden die Daten mit ReadLn und einem Timeout (500) gelesen. Wenn Daten da sind. Daten in Befehl umwandeln. Wenn Befehl Ping sende Pong zurück, wenn andere Daten an fOnRead weitergeben zum verarbeiten. - Es wird kein CriticalSection verwendet. - Methode OnTimeAlive, hier prüft der Server anhand einer Liste welche Clients online sind, wenn Client nicht auf Ping antwortet, Verbindung trennen. Der Client / TIdTCPClient - Der Client läuft als Thread. - Execute vom Thread: prüfen ob Client Online ist, wenn nicht anmelden. - Execute vom Thread: Daten da, wenn nein exit, wenn ja Daten weiter an fOnRead geben - Methode Send. Sendet Daten an Server. Erst ein Ping senden und auf ein Pong warten, wenn Pong ok, dann Daten senden, wenn nicht exit und Verbindung neu aufbauen. - Es wird kein CriticalSection verwendet. - Per Timer sendet der Client zum Test einen String zum Server. Soweit so gut, aber irgend wie komme ich noch wo durcheinander so das mein Client einfriert. (Noch ne frage, bei den Sockets habe ich die Befehle in einer Jobliste verarbeitet, heist wenn ein job nur halb gesendet wurde, wird gewartet bis dieser ganz da ist und erst dann weiter gegeben, wie ist das bei den Indys. Muss ich mich auch drum kümmern, wenn ein Befehl zu groß ist das dieser auch ganz ankommt? Glaube das mit den Indy Threads habe ich noch nicht ganz verstanden :( ) Mfg |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Hi Jackie,
der Source-Code im Posting davor lässt "leider" noch ganz klar darauf schliessen das Du Indy9 verwendest, was auch nicht schlimm ist, Dein Problem bekommst Du mit Indy9 oder Indy10 gelöst. Wie Du allerdings am besten von Indy9 auf Indy10 umstellst, kann Du hier nachlesen, achte besonders auf Assertot's Antwort. Unabhängig davon nochmal zu Deinem Problem, wenn ich ein wenig Luft hätte würde ich Dir ja ne kleine Demo mit Client & Server schreiben. Allerdings ist ist bei mir im Moment alles andere mehr verfügbar als Zeit :roll: Nochmal zum vorgehen, der Client sollte wie von Dir auch schon genannt in einem eigenen Thread laufen. Der Server(egal ob Indy9/Indy10) behandelt alles intern schon in Threads, Du brauchst KEINE(N) extra Thread(s) erzeugen. DU DARFST AUF KEINEN FALL EINE SCHLEIFE INS ONEXECUTE DES SERVERS BAUEN ! Das OnExecute läuft selber schon in der Schleife eines Indy internen Threads, d.h. solange der Client connected ist tritt immer wieder das OnExecute ein !! Deine "Jobliste" brauchst Du bei Indy nicht, das behandeln die alles intern, ReadLn liefert erst Daten zurück wenn auch ein CRLF angekommen ist. Ich denke Dein Fehler liegt im Servercode, kannst Du denn nicht komplett posten ? Greetz Data |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Hi Data,
danke erst mal das du dir die Zeit nimmst das ganze mit mir durchzugehen. Eventuell noch als Hinweis. Die Befehle die versendet werden sehen so aus.
Delphi-Quellcode:
Denke werde es aber so machen wie ich hier im Beispiel gefunden habe.
TSocketPaket = record
//Header sizeGesamt : integer; sizeDaten : integer; Command : TCommand; //Daten daten : TStringlist; end; function TCommandHandling.SendFrames: String; var datastring, FFrames : string; size : integer; begin datastring := fSocketPaket.daten.CommaText; //4 = Integer / Geaamtlänge //4 = Integer / Befehl //4 = Integer / Länge Daten // = 12 SetLength(FFrames,12+Length(datastring)); ZeroMemory(Pchar(FFrames),Length(FFrames)); //1-4 -> gesamtlänge PCardinal(@FFrames[1])^ := Length(fframes); //gesamtlänge //5-8 -> befehl PCardinal(@FFrames[5])^ := Integer(fSocketPaket.Command); //9-12 -> länge daten PCardinal(@FFrames[9])^ := Length(datastring); //13-x -> daten size := length(datastring); if datastring <> '' then System.Move(Pchar(datastring)^,Pointer(@FFrames[13])^,Size); result := FFrames; end; Also so in der Art. Starte Kommunikation, warte auf antwort, sende Daten, warte auf Antwort, sende Daten, ...., beende Kommunikation. Warte auf Kommunikation Start... Das ist der Server.
Delphi-Quellcode:
Mfg
unit DTS_Server;
interface uses Windows, Classes, IdTCPServer, SysUtils, DTS_Command, DTS_Utils, IdSocketHandle, SyncObjs, Contnrs; Type TServerOnRead = Procedure(AThread: TIdPeerThread; Data : TCommandHandling) of object; TServerOnEvent = Procedure(AThread: TIdPeerThread) of object; TClientData = class(TObject) private fDNS : String; { Hostname } fConnected, { Time of connect } fLastAction : TDateTime; { Time of last transaction } fThread : Pointer; { Pointer to thread } public Property DNS : String read fDNS write FDNS; Property Connected : TDateTime read fConnected write fConnected; Property LastAction : TDateTime read fLastAction write fLastAction; Property Thread : Pointer read fThread write fThread; end; TDTSServer = class(TThread) private fPort : Integer; fClientList : TobjectList; fServer : TIdTCPServer; fOnRead : TServerOnRead; fOnDisconnect : TServerOnEvent; fBindIP : String; Procedure OnExecute(AThread: TIdPeerThread); Procedure OnConnect(AThread: TIdPeerThread); Procedure OnDisconnect(AThread: TIdPeerThread); public Constructor Create(Port : integer; BindIP : String = '127.0.0.1'); Destructor Destroy; override; Procedure Broadcast(Data : TCommandHandling); Property OnClientReadData : TServerOnRead read fOnRead write fOnRead; Property OnClientDisconnect : TServerOnEvent read fOnDisconnect write fOnDisconnect; protected Procedure Execute; override; Procedure DoTerminate; override; end; implementation { TDTSServer } procedure TDTSServer.Broadcast(Data: TCommandHandling); var i : integer; RecClient : TClientData; RecThread : TIdPeerThread; begin try for i := 0 to fClientList.Count-1 do // iterate through client-list begin RecClient := TClientData(fClientList.Items[i]); // get client-object RecThread := RecClient.Thread; // get client-thread out of it RecThread.Connection.WriteLn(Data.SendFrames); // send the stuff end; finally FreeAndNil(Data); end; end; constructor TDTSServer.Create(Port: integer; BindIP : String = '127.0.0.1'); begin inherited Create(false); fPort := Port; fBindIP := BindIP; end; destructor TDTSServer.Destroy; begin self.Terminate; self.WaitFor; inherited; end; procedure TDTSServer.DoTerminate; begin inherited; end; procedure TDTSServer.Execute; var MSG : TMsg; Binding : TIdSocketHandle; begin inherited; fClientList := TObjectList.Create; fServer := TIdTCPServer.Create(nil); // fServer.TerminateWaitTime := 3000; fServer.Bindings.Clear; Binding := fServer.Bindings.Add; Binding.IP := fBindIP; Binding.Port := fPort; fServer.OnExecute := OnExecute; fServer.OnConnect := OnConnect; fServer.OnDisconnect := OnDisconnect; fServer.Active := true; while not Terminated do begin sleep(100); end; // while (GetMessage(msg, 0, 0, 0) and not Terminated) do // DispatchMessage(msg); fServer.Active := false; FreeAndNil(fServer); FreeAndNil(fClientList); end; procedure TDTSServer.OnConnect(AThread: TIdPeerThread); var Data : TClientData; begin Data := TClientData.Create; Data.DNS := AThread.Connection.LocalName; Data.Connected := Now; Data.LastAction := Now; Data.Thread := AThread; AThread.Data := TClientData(Data); fClientList.Add(Data); end; procedure TDTSServer.OnDisconnect(AThread: TIdPeerThread); var Data : TClientData; begin if(Assigned(fOnDisconnect)) then fOnDisconnect(AThread); Data := TClientData(AThread.Data); fClientList.Remove(Data); AThread.Data := nil; end; procedure TDTSServer.OnExecute(AThread: TIdPeerThread); var msg : string; cmd : TCommandHandling; begin AThread.Connection.ReadTimeout := 1000; try msg := AThread.Connection.ReadLn; except exit; end; cmd := TCommandHandling.Create(CMDPong); try cmd.SetFrames(msg); if cmd.GetCmd = CMDPing then begin cmd.SetCommand(CMDPong); AThread.Connection.WriteLn(cmd.SendFrames); end else begin if Assigned(fOnRead) then //Weiter an die eigentliche Command behandlung. fOnRead(AThread, cmd); end; finally FreeAndNil(cmd); end; end; end. |
AW: TIdTCPServer / TIdTCPClient => Ping - Pong
Hi Jackie,
schonmal kurz vorab : Der Server darf/sollte nicht innerhalb eines TTHreads laufen, das war vielleicht bei Deinen Sockets erforderlich, aber bei Indy ist das so nicht gewollt, weil Indy intern selber alles in Threads handelt. Also leite Deine Klasse "TDTSServer" NICHT von TThread ab, sondern lass das ganze mal als einfache Klasse laufen. OnExecute und OnTerminate ersetzt Du dann mit Sart und Stop oder wie auch immer Du es brauchst. Greetz Data |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz