AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke TCP-Verbindung zu mehreren Endgeräten
Thema durchsuchen
Ansicht
Themen-Optionen

TCP-Verbindung zu mehreren Endgeräten

Ein Thema von LokutusvB · begonnen am 9. Feb 2018 · letzter Beitrag vom 19. Feb 2018
Antwort Antwort
LokutusvB

Registriert seit: 18. Jul 2006
277 Beiträge
 
Delphi XE6 Enterprise
 
#1

TCP-Verbindung zu mehreren Endgeräten

  Alt 9. Feb 2018, 12:59
Moinsen,

ich habe in einem Netzwerk mehrere Geräte (Server), mit denen ich mich verbinden muß. Wird bei den Geräten ein Ereignis ausgelöst, sendet dieses Gerät einen String. Mit meinem programmierten Client kann ich diesen String auch empfangen und auswerten.

Für mein Testprogramm nutze ich Delphi XE6 und TIDTCPClient sowie TiDThreadComponent.

Ich verbinde mich mit dem Client zu einem Endgerät, setze idThreadComponent auf Active und im OnRun Ereignis der idThreadComponent führe ich ein IdTCPClient.IOHandler.ReadLn durch. Werden Daten gelesen, kann ich sie verarbeiten.

Soweit klappt alles wunderbar. Nun allerdings kommt das Problem. Ich habe fortan eine variable Anzahl von Endgeräten. Ich habe noch keine brauchbare Lösung finden können, wie ich mit vorgegebenen Mitteln von TCPClient und ThreadKomponent mich mit den Geräten verbinden kann und dann Daten von jedem Endgerät empfangen kann. Führe ich in der Run-Methode der ThreadKomponent ein ReadLn aus, wartet die Methode an der Stelle, bis das entsprechende Endgerät Daten liefert. Daten von anderen Endgeräten können in der Zeit nicht gelesen werden. Kann ich die Problematik überhaupt mit diesen beiden Indy-Komponenten lösen? wenn ja, wie ist der Ansatz?

Oder geht das nur über WindowsSockets und für jede Verbindung einen Thread starten der ständig ein WSAREcv ausführt?
MFG
LokutusvB
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: TCP-Verbindung zu mehreren Endgeräten

  Alt 9. Feb 2018, 13:07
Ein Client = ein Server gleichzeitig (oder mehrere nacheinander/abwechselnd)

mehrere Clients = mehrere Server


Also egal welche Kompnenten zu verwendets:
* so lange das Lesen blockierend ist, kannst du mit einem Thread nicht mehreres gleichzeitig verarbeiten.
* also pro Server eine Client-Komponente
** haben die Klientomponenten ein OnReciveEreignis brauchst du nicht unbedingt thrads
** ansonsten auch pro Komponente ein Thread, bzw. für jeden Thread seine eigene Client-Komponente
$2B or not $2B
  Mit Zitat antworten Zitat
LokutusvB

Registriert seit: 18. Jul 2006
277 Beiträge
 
Delphi XE6 Enterprise
 
#3

AW: TCP-Verbindung zu mehreren Endgeräten

  Alt 19. Feb 2018, 15:39
Hi himitsu,

danke für deine klärenden Worte. Ich bin ein großes Stück weiter gekommen, bin mir aber nicht sicher, ob diese Lösung "sauber" und fehlerfrei Seitens Delphi Threads ist.

In meiner Hauptform habe ich ein type tcpDataClients als Record angelegt:

Delphi-Quellcode:
tcpDataClients = record
 recIndex: Integer;
 tsC: TidTCPClient;
 ...
end;
Hier werden unter anderem der Indy-Client und der Index pro Server, mit dem ich mich verbinden muß, abgelegt. Da das ganze variabel gehalten werden muß, habe ich ein Array des Records vereinbart und lese in FormCreat aus einer Ini-Datei die IP-Serveradressen ein und erzeuge die Indy-Clients. Anschließend werden die Verbindungen hergestellt.

Jetzt folgt der Teil, in dem ich mir nicht sicher bin, ob das ausfallsicher ist.

In einer Thread-Klasse übergebe ich im Konstruktor eine Variable an eine als private deklarierte Variable der Thread-Klasse. In jedem anderen Beispiel im Netz, das ich während meiner Suche gefunden habe, wird immer mit einem Pointer gearbeitet (wahrscheinlich da nur eine Variable genutzt wird).

Delphi-Quellcode:
Constructor TT_Lesen.Create;
begin
  Inherited Create(False);
  tcpRecIndex := Variable;
end;
Nun kann der Datenabruf der einzelnen Indy-Clients beginnen.

Delphi-Quellcode:
procedure TF_Main.Start;
var
  ii: Integer;
begin
  for ii := 0 to Length(tcpCls) - 1 do begin
    tcpCls[ii].recIndex := ii;
    tcpCls[ii].Lesen_Thread := TT_Lesen.Create(tcpCls[ii].recIndex);
    tcpCls[ii].Lesen_Thread.Priority := tpNormal;
    tcpCls[ii].Lesen_Thread.Resume();
  end;
end;
Diese ist noch ganz einfach gehalten, ohne Kontrolle ob ein Thread bereits aktiv ist. Darum geht es mir aber auch nicht, sondern die Variable, die übergeben wird. Der Variable recIndex wird der Wert der Schleifenvariable zugewiesen und dem Thread übergeben. Im Thread wird diese tcpRecIndex vergeben und im Thread kann so dank dem Index das richtige Array Record Element angesprochen werden. Wie z.B.
txt := Trim(F_Main.tcpCls[tcpRecIndex].tsC.IOHandler.ReadLn());
Ist diese Lösung fehleranfällig oder kann man das in die Praxis umsetzen? Oder ist es besser, wenn ich direkt den Record an den Thread übergebe?
MFG
LokutusvB

Geändert von LokutusvB (19. Feb 2018 um 16:08 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:04 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