Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy TCP Client Server - Verständnisproblem (https://www.delphipraxis.net/140203-indy-tcp-client-server-verstaendnisproblem.html)

DelphiPeter 13. Sep 2009 15:27


Indy TCP Client Server - Verständnisproblem
 
Hallo Delphi Freunde

Ich bastel gerade an einem kleinen Chat mit Indy Komponenten.

Nun würde ich gerne eine Nachricht vom einen Client über den Server an einen anderen Client schicken. Es können aber mehrere Clients über ein und die selbe IP-Adresse angemeldet sein. Woher weiß ich jetzt, an welchen der CLients, die hinter der einen IP-Adresse steckt, die Nachricht gesendet werden soll, denn die IP ist ja immer gleich? :gruebel:

Hinzu kommt, das ich nicht weiß, wie ich einen Client ansprechen soll.

Klar ist, das ich mit z.B. AContext.Connection.IOHandler.WriteLn eine Nachricht an den Client schicken kann, der gerade anfragt.

Hach mensch, kann mir da mal jemand helfen?


Danke

Peter

SimStar001 13. Sep 2009 16:12

Re: Indy TCP Client Server - Verständnisproblem
 
wenn du die nachricht per text schickst, wovon ich mal ausgehe, kannst du vor den text ja noch ne art variable hängen, die festlegt wer die message bekommen soll... z.b. den user namen oder so...

XXcD 13. Sep 2009 16:24

Re: Indy TCP Client Server - Verständnisproblem
 
Such mal in der DP Suche nach Athread.Data da kannst du beispielsweise die Clientdaten hinterlegen.

g1o2k4 13. Sep 2009 16:27

Re: Indy TCP Client Server - Verständnisproblem
 
Zitat:

Zitat von DelphiPeter
Nun würde ich gerne eine Nachricht vom einen Client über den Server an einen anderen Client schicken. Es können aber mehrere Clients über ein und die selbe IP-Adresse angemeldet sein. Woher weiß ich jetzt, an welchen der CLients, die hinter der einen IP-Adresse steckt, die Nachricht gesendet werden soll, denn die IP ist ja immer gleich? :gruebel:


am einfachsten wäre es jedem clienten nen eigenen port zu geben und darüber zu schicken.
aber ich glaube man kann auch beim server die clienten nach clientindex unterscheiden. zumindest ging das früher bei tsocket komponenten so, da hab ich das mal gemacht, denke indy wird auch so eine möglichkeit haben. wenn die clienten zum server connecten gibt der ihnen eine nummer um sie auseinanderhalten zu können.

XXcD 13. Sep 2009 16:32

Re: Indy TCP Client Server - Verständnisproblem
 
lol nen eigenen port dann müsstest du ja für jeden client nen eigen server aufsetzen :)
Versuch das mal so:

Delphi-Quellcode:
TClientInfo = class(TObject)
  Thread: TIdPeerThread;

  User: string; // z.B. auch den Benutzernamen mit ablegen
end;

...

uses Contnrs;
...
private
  FClients: TObjectList; // TObjectList gibt die Items automatisch frei.
end;

...

procedure TfrmMain.tcpServerConnect(AThread: TIdPeerThread);
var Client: TClientInfo;
begin
  ClientInfo := TClientInfo.Create; // erzeugen für diesen Client
  ClientInfo.Thread := AThread; // IdPeerThread zuweisen
  AThread.Data := ClientInfo; // auch in die anderen Richtung verknüpfen

  FClients.Add(ClientInfo); // und TClientInfo Instanz zur Client-Liste hinzufügen
end;

...

var Client: TClientInfo;
begin
  Client := TClientInfo(AThread.Data); // in OnConnect wurde AThread.Data auf die ClientInfo gesetzt
  AThread.Data := nil; // Verknüpfung lösen
  FClients.Remove(ClientInfo); // ClientInfo aus der Client-Liste löschen und freigeben
end;
Quelle: http://forum.delphi-treff.de/showthread.php?t=1571

Schau mal ob du damit was anfangen kannst.
Wenn nicht dann schreib ich dir da kurz was

DelphiPeter 13. Sep 2009 16:52

Re: Indy TCP Client Server - Verständnisproblem
 
Hm, mal sehen ob ich daraus was machen kann.

Ich gebe jedem Chat CLient nach dem Login eine eindeutige ID, speichere die IP, eine Email Adresse (die eindeutig ist) und dir Uhrzeit des Logins sowie einen nicknamen in einer MysQL Datenbank.

Das senden einer Nachricht von der aktuellen Verbindung an eine bestimmte ID wäre eben das was ich brauche. Aber vielleicht komme ich ja mit diesem Beispiel ein wenig weiter.

XXcD 13. Sep 2009 16:58

Re: Indy TCP Client Server - Verständnisproblem
 
Ich würde dir auch empfehlen beim senden der daten einen bestimmten standart festzulegen.

Beispielsweise so:
Code:
0105Das ist eine Testnachricht
Dabei wäre das dann so aufgebaut:
01 = Id des users an den die Nachricht geht
05 = Beispielsweise eine Paketid um festzulegen was passiert(Nachricht an einen Client senden).
Das ist ... = Wäre dann halt die Nachricht selbst

Dann könntest du ja eine Funktion basteln die die einzelnen Teile ausliest

DelphiPeter 13. Sep 2009 17:47

Re: Indy TCP Client Server - Verständnisproblem
 
Hi

also mein Standard ist schon recht gut ausgearbeitet, wo ich hänger ist in deinem beispiel beim serverconnect. Bei Mir gibt es keine tclientinfo, das sieht bei mir so aus

Delphi-Quellcode:
procedure TfmMain.TCPServerConnect(AContext: TIdContext);

DataCool 14. Sep 2009 08:16

Re: Indy TCP Client Server - Verständnisproblem
 
Hi,

im oben genannten Beispiel ist TClientInfo eine selber definierte Klasse,
die allerdings auf das arbeiten mit Indy9 abzielt(zu erkennen an TidPeerThread).
Da Du mit Indy10 arbeitest müßte bei Dir anstatt des IdPeerThread der IdContext gespeichert werden.

Im OnConnect musst Du ja auch selber eine Instanz von TClientInfo erzeugen ,
mit Werten füllen und in AContext.Data ablegen.

Greetz Data

DelphiPeter 15. Sep 2009 17:08

Re: Indy TCP Client Server - Verständnisproblem
 
So Leute, nun habe ich es versucht mal so umzusetzen.

Meine TClientInfo Klasse sieht nun so aus
Delphi-Quellcode:
  TClientInfo = class(TObject)
    Thread: TIdContext;
    Email: string;
    GUID: string;
    Nickname: string;
    IP: string;
    LoggedIn: Boolean;
    LogonTime: string;
    Send: boolean;
    SendMode: String;
    SendTo: string;
  end;

Jetzt kommt eine Anfrage von AContext im OnExecute Ereignis. Die Nachricht soll an eine bestimmte E-Mail Adresse gehen, welche ja in TClientInfo erfasst wurde. Alle Clients die sich verbinden, werden in eine Objektliste FCLients gespeichert.

Wie sende ich nun eine Nachricht an den Client mit einer bestimmten E-Mail Adresse?

Habe es mal so versucht..
Delphi-Quellcode:
...
                found := false;
                for I := 0 to FCLients.Count - 1 do begin
                  BClient := TClientInfo(FClients.Items[I]);
                  if BClient.Email = request_param2 then begin
                    // Nachricht senden...
                    found := true;
                    BClient.Thread.Connection.IOHandler.WriteLn('RECV TEXT '+ request_param3);
                  end;
                end;
...

So richtig funktionieren tut das aber leider nicht. Die erste Nachricht wird gesendet... und dann passiert nur noch Kuddelmuddel. Der eine Client sendet was und empfängt es selber, dann bekommt ein anderer Client die Meldungen vom Server zurück. Verstehe nur noch Bahnhof.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:55 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