![]() |
Problem mit case-of Anweisung in ClientSocket1Read
Hallo Leute,
ich programmiere da gerade für ein Projekt an meiner Uni eine Client/Server Anwendung und da gibt es die eine Stelle im noch nicht fertigen Programm, die mich rätzeln läßt. Und zwar habe ich eine GUI mit mehreren Buttons. Je nachdem welcher Button gedrückt wird, erhält die globale und als public deklarierte Variable erg einen anderen Wert. Außerdem wird bei dem Klicken auf einen Button eine Nachricht an den Server geschickt, der dann je nach Nachricht ein anderes string-array zurückschickt. Bis hierher klappt auch alles wie es soll. Jetzt komme ich zu dem Problem und zwar müssen unterschiedliche arrays beim Empfang dann auch unterschiedlich verarbeitet werden. Dazu gibt es die bereits erwähnte Variable erg, welche dann mit einem case of die unterschiedlichen "Fälle" bearbeitet. Das eigentliche Problem ist das, die untenstehende showmessage Anweisung in Fall 3 des case of aus mir nicht erklärlichen Gründen immer zweimal ausgeführt wird. Einmal mit und einmal ohne den Inhalt vom Feld edit17.
Delphi-Quellcode:
Sicher ist das für euch Experten hier kein Problem, aber ich komme einfach nicht dahinter was der Grund ist. Das komische ist, wenn ich es schrittweise ablaufen lasse, kommt die Meldung wie gewünscht nur einmal.
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket); var daten: array[0..10,0..10] of string[20]; //In diesem Unterprogramm werden alle vom Server kommenden Meldungen geprüft und entsprechend verarbeitet begin socket.ReceiveBuf(daten,SizeOf(daten)); //mit Ereignisstatus prüfen, welcher Button gedrückt wurde case erg of 1: showmessage('noch nicht belegt 1'); 2: showmessage('noch nicht belegt 2'); 3: begin edit17.Text:=daten[1,1]; showmessage('Kontostand: ' +edit17.text); erg:=0; end; 4: showmessage('noch nicht belegt 4'); else showmessage('Ich weiß nicht was ich mit den Daten tun soll.') end; erg:=0; end; Vielleicht kann mir ja einer von euch weiterhelfen. Vielen Dank für eure Hilfe sagt schon mal Fran |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Hi,
ich denke mal das Problem ist, dass du die Daten teilweise zu früh abholen möchtest / abholst. Wenn du den Einzelschrittmodus benutzt, nun ja, bist halt deutlich langsamer als die Datenübertragung, die CPU nicht. Also wenn du einfach darauf reagierst, dass etwas ankommt, solltest du sicher sein, dass sich im Buffer >= sizeOf(daten) befindet. Wenn dein Empfangspuffer nur ein Byte enthält (mal ganz übertrieben), dann kannst du zwar in Daten etwas einlesen, aber an den meisten Stellen (bis auf dem ersten byte alle) wäre das dann undefiniert. Somit zeigt dir dein Showmessage schon was mit dem Edit17.Text an, nur ist der halt leer. Da die CPU recht schnell ist, wird gleich danach das richtige Wort ins Edit17 geschrieben und du siehst das nur nicht. Bin mir nicht ganz sicher, aber sollte ich richtig liegen, sollte immer der erste Aufruf das leere Edit17 anzeigen. By the way, benenn lieber Edit17 um, je früher desto weniger nervig! |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Zitat:
P.S. Das Edit17 wird zusammen mit den anderen Edits, Labels usw. demnächst umbenannt. Erst gibt es bei mir nämlich immer eine gewisse Zeit, wo ich nur teste und zum Testen gibt es bei mir mehrere Testbuttons, Edits, Labels usw. Und nur fürs Testen, denen allen einen Namen zu geben ist mir zu aufwändig. Den Namen verdienen die sich erst wenns sozusagen richtig los geht. |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Nun ja, es erklärt warum das Showmessage zweimal kommt in sofern, dass du ja einen Empfangspuffer hast. Und der wird in n-Schritten gefüllt. D.h. bei jedem (asynchronen) Eintreffen von Daten wird die Ereignisbehandlung für das Eintreffen von Daten ausgelöst. Bei den ersten Bytes (die noch nicht vollständig Daten enthalten) -> Erstes ShowMessage, bei dem Rest -> zweites ShowMessage.
Da sleep aber glaube ich den ganzen Prozess lahm legt, solltest du lieber in einer Schleife warten, die auch weitere Prozessabläufe erlaubt. Du solltest aber mal gucken, wieviele Bytes wirklich gelesen wurden (rückgabewert von socket.ReceiveBuf), wenn der sich von SizeOf(Daten) unterscheidet, liegt es wohl daran.
Delphi-Quellcode:
if Socket.ReceiveBuf(daten, SizeOf(daten)) <> SizeOf(daten) then
begin ShowMessage('Aha, noch nicht alles da'); end; |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Zitat:
Da ich dachte Socket.ReceiveBuf(daten, SizeOf(daten)) ist vielleicht nicht das selbe wie SizeOf(daten) habe ich es mal mit socket.receivelength probiert, was aber leider auch nicht ging. Vielleicht kannst du mir ja einen heißen Tipp geben, wie es in etwa gehen könnte. |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Versuche es mal nicht mit Showmassage sondern lass die Nachricht einem Memo zuzukommen. Prüfe mal dann ob es klappt.
Ausserdem sollte man grundsätzlich keine Messageboxen in der ClientSocket1Read Routine ausführen. Da diese die Prozedure ClientSocket1Read stoppen bis du eben auf OK klickst. Gruß net7 |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Zitat:
|
Re: Problem mit case-of Anweisung in ClientSocket1Read
Herzlich willkommen in der Delphi-PRAXiS, Fran.
Wenn ich mir deinen Code so ansehe - erwartest du wirklich 100 Standard Pascal Strings der Größe 20 zzgl. Längen-Byte? Außerdem ist es üblich die Empfangsdaten in einer Queue zu verarbeiten - ReceiveBuf schiebt den Schreib-Index und deine Leseroutine schiebt den Lese-Index. Grüße vom marabu |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Zitat:
Falls du dich fragst, warum ich kein dynamisches array nehme, wenn ich nicht genau weiß wieviel denn nun genau ankommt. Das hat den Grund, das es mit dem Senden von dynamischen arrays nicht so geklappt hat, deshalb habe ich einfach ein statisches genommen. Zitat:
CU Fran |
Re: Problem mit case-of Anweisung in ClientSocket1Read
Liste der Anhänge anzeigen (Anzahl: 1)
Mit deinem zweidimensionalen Array implizierst du eine Struktur deiner Empfangsdaten, die gar nicht vorhanden ist - wenn ich dich richtig verstehe. Das bringt uns wieder auf die Queue. Ich selbst favorisiere einen ring buffer, bei dem sich Schreib- und Lese-Index ein Wettrennen liefern. Ich habe dir mal eine Unit angehängt, die dir das Prinzip verdeutlichen kann. Viel Spass beim Studieren des Codes.
marabu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz