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? |
AW: Problem mit IdTCPServer/Client und ReadBytes
Sollte es nicht reichen, die Erreichbarkeit vor dem Befehl zu Testen?
|
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? |
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. |
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). |
AW: Problem mit IdTCPServer/Client und ReadBytes
Event hier mal nachsehen .... http://sourceforge.net/projects/indy10clieservr/
|
AW: Problem mit IdTCPServer/Client und ReadBytes
Zitat:
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. |
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.
|
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