Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Problem mit IdTCPServer/Client und ReadBytes (https://www.delphipraxis.net/180832-problem-mit-idtcpserver-client-und-readbytes.html)

Weeze14 21. Jun 2014 14:49


Problem mit IdTCPServer/Client und ReadBytes
 
Ich arbeite seit kurzer Zeit mit den Indy's und IdTCPServer und Client.
Ich habe einen Client, der regelmäßig Anfragt, ob der Server noch online ist.
Dafür sendet der Client dem Server ein paar Bytes, der Server antwortet mit ein paar Bytes, die der Client dann einliest und verarbeitet.

Möchte ich mit dem Client aber einen Befehl an den Server starten, so blockt dieser Server-Erreichbarkeits-Thread irgendetwas.

Grob gesagt: während der Client einen Befehl X ausführt, darf kein Read-Befehl im Server-Erreichbarkeits-Thread ausgeführt werden.
Das habe ich unterbunden, indem ich en Thread schlafen lege, bis der Befehl X abgearbeitet ist.
Aber sehr oft schickt der Server seine "Ich bin noch online"-Antwort genau dann, wenn der Befehl X schon ausgeführt wird und der Server-Erreichbarkeits-Thread bereits schläft.
Ein Read-Befehl im Befehl X gibt somit die Antwort "Ich bin noch online", obwohl da was ganz anderes kommen sollte.

IdTCPClient.IOHandler.InputBufferIsEmpty und IdTCPClient.IOHandler.InputBuffer.Size ergeben immer False oder 0.

Wie kann ich solch ein problem verhindern?
Und kann ich irgendwie prüfen, ob der Input (das was vom Server gesendet wird) "leer" ist? Also ob bereits alles gelesen wurde?

mkinzler 21. Jun 2014 14:52

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Sollte es nicht reichen, die Erreichbarkeit vor dem Befehl zu Testen?

Weeze14 21. Jun 2014 14:57

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Interessant. Leider beschäftige ich mich noch nicht allzu lange mit den Indy's. Wie prüft man das denn genau?

Ich bin mir aber auch nicht so sicher, ob das eine gute Idee ist. Denn in dem Code auf dem Server, der den "ich bin online"-Befehl zurückschickt, werden auch andere Befehle zurückgeschickt, falls notwendig.

Kann man denn, falls noch Daten, die der Server an den Client schickt, "lesbar" sind, diese nicht löschen?

sx2008 23. Jun 2014 06:55

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Deine Vorstellung du könntest direkt "Befehle" vom Client zum Server schicken ist falsch.
Der Client mag zwar eine zusammengehörige Bytefolge schicken; ob diese Bytes als zusammengehörende Folge beim Server so ankommen ist mehr als unsicher.
Als Programmierer muss man sich also selbst darum kümmern die Befehle zu trennen.
Dazu kann man z.B. ein Trennzeichen definieren damit man weiss wo der letzte Befehl aufhört und der Nächste beginnt.

Ob der Serverthread für eine gewisse Zeit blockiert ist spielt kaum eine Rolle, denn die Daten werden vom Betriebssystem gepuffert.
Sobald der Thread wieder Zeit hat kann er die in der zwischenzeit eingetroffenen Bytes bearbeiten.
Natürlich kann es dann sein dass schon 2 oder mehr Befehle (und der letzte vielleicht nur zur Hälfte) eingetroffen sind.

Dejan Vu 23. Jun 2014 07:31

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Sehr praktisch in diesem Zusammenhang (falls ich die Problematik verstanden habe), ist ein Workerthread auf Clientseite. Der Workerthread verwaltet eine Liste von Jobs. Jeder Job kümmert sich z.B. um einen Query/Response-Zyklus per TCP. Oder verschickt nur die Daten (dann muss die Antwort asynchron dem Job zugeordnet werden).

Im einfachen Fall (also dem synchronen Query/Response) hast Du einen Timer, der die Alive-Anfragen einfach in die Jobliste einfügt. Wenn Du nun etwas vom Server willst, erzeugst Du einen entsprechenden Job und fügst in auch einfach in die Liste ein. Er wird dann 'schnellstmöglich' abgearbeitet, nämlich entweder sofort (der Workerthread hatte gerade nichts zu tun), oder später (wenn der WT den aktuellen Job gerade abarbeitet), oder noch später (wenn noch andere Jobs in der Warteschlange/Jobliste sind).
Auf jeden Fall wird ja so sichergestellt, das jeder Query-Response-Zyklus garantiert isoliert abgearbeitet wird und damit sollten deine 'Client-wird-mit-Antworten-zu-vorherigen-Anfragen-verwirrt'-Probleme gelöst sein.

@mkinzler: Was verstehst du unter 'Erreichbarkeit testen'? Nur weil die Connection noch aktiv ist, heißt es ja nicht, das man wirklich eine Verbindung hat. Diese Form des 'Ping', oder 'Alive' mit Sequenzzähler ist immer da extrem wichtig, wo man unbedingt wissen muss, ob die Gegenstelle erreichbar ist. Es wäre auch denkbar, das Client und Server wirklich aus dem Tritt sind (d.h. Frage X wird mit Antwort Y-1 beantwortet). In diesem Fall würde ein Ping zwar sagen 'Alles Roger', aber die Kommunikation ist im Eimer. Eine spezielle 'Alive?'-Anfrage mit Sequenznummer dagegen erkennt zuverlässig, ob die Welt noch in Ordnung ist und trennt die Verbindung ggf. (und baut sie dann wieder auf).

bernhard_LA 23. Jun 2014 21:33

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Event hier mal nachsehen .... http://sourceforge.net/projects/indy10clieservr/

himitsu 24. Jun 2014 02:41

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Zitat:

Zitat von sx2008 (Beitrag 1263201)
Deine Vorstellung du könntest direkt "Befehle" vom Client zum Server schicken ist falsch.
Der Client mag zwar eine zusammengehörige Bytefolge schicken; ob diese Bytes als zusammengehörende Folge beim Server so ankommen ist mehr als unsicher.
Als Programmierer muss man sich also selbst darum kümmern die Befehle zu trennen.
Dazu kann man z.B. ein Trennzeichen definieren damit man weiss wo der letzte Befehl aufhört und der Nächste beginnt.

Jupp, entweder man macht alles selber,
oder man macht es nicht selber und legt noch eine Schicht dazwischen, welche diese Arbeit übernimmt.
DataSnap/MIDAS, RemObjects, REST, SOAP, PPC, ... und selbst HTTP, FTP, IRC usw. sind praktisch soeine weitere Schicht, welche für bestimmte Aufgaben ausgelegt sind.

TCP ist halt nur das Übertragungssteuerungsprotokoll (Transmission Control Protocol), welches sich ausschließlich um die Datenübertragung kümmert.
Ob und wie die Daten danach verarbeit und "gruppiert" werden, ist dem Ding sowas von egal und es hat sich darum auch garnicht zu kümmern. Es sorgt nur dafür, daß die Daten drüben ankommen und gruppiert und/oder teilt/portioniert die Daten einfach so, wie es für den Transport besser/nötig ist.
Das Sammeln/Zusammenfassen und Auswerten gehört dann in die nächste Schicht. Also du, oder noch eine weitere Zwischenschicht.

Dejan Vu 24. Jun 2014 08:03

AW: Problem mit IdTCPServer/Client und ReadBytes
 
Der Sinn der Indies ist doch gerade der, ein wenig mehr als nacktes TCP zu bieten. Man hat doch schon die Möglichkeit, Befehle in Gänze zu lesen, Indy puffert das ja schon zwischen. Hier wird sicherlich keine Zwischenschicht benötigt. Und wenn, würde man die sich ganz sicher selbst schreiben, alleine schon, um etwas zu lernen.

himitsu 24. Jun 2014 08:19

AW: Problem mit IdTCPServer/Client und ReadBytes
 
So hab ich das nicht gesagt und nur ein paar "Technologien" genannt.

Indie bietet natürlich meht als nur TIdTCP und TIdTCPServer, um eine Verbindung aufzubauen, sondern auch schon darauf aufbauende Technologien:
TIdCmdTCPClient TIdCmdTCPServer
TIdFTP TIdFTPServer
TIdIRC TIdIRCServer
TIdHTTP TIdHTTPServer
...


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