Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Problem mit case-of Anweisung in ClientSocket1Read (https://www.delphipraxis.net/56379-problem-mit-case-anweisung-clientsocket1read.html)

fran 4. Nov 2005 19:10


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:
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;
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.
Vielleicht kann mir ja einer von euch weiterhelfen.

Vielen Dank für eure Hilfe sagt schon mal Fran

Der_Unwissende 4. Nov 2005 19:28

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!

fran 4. Nov 2005 19:39

Re: Problem mit case-of Anweisung in ClientSocket1Read
 
Zitat:

Zitat von Der_Unwissende
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!

Das erklärt aber immer noch nicht warum das showmessage zweimal kommt. Ich habs schon mit einem sleep(500) probiert, hat aber nichts bewirkt außer das die GUI für 500 ms lahm gelegt war.



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.

Der_Unwissende 5. Nov 2005 07:42

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;

fran 5. Nov 2005 14:17

Re: Problem mit case-of Anweisung in ClientSocket1Read
 
Zitat:

Zitat von Der_Unwissende
Da sleep aber glaube ich den ganzen Prozess lahm legt, solltest du lieber in einer Schleife warten, die auch weitere Prozessabläufe erlaubt.

Delphi-Quellcode:
  if Socket.ReceiveBuf(daten, SizeOf(daten)) <> SizeOf(daten) then
    begin
      ShowMessage('Aha, noch nicht alles da');
    end;

Stimmt sleep legt den ganzen Prozess lahm, deshalb gings ja auch nicht. Ich habe jetzt mal testweise dein Beispiel verwendet (natürlich mit = statt <>), aber leider kommt dann die Meldung gar nicht mehr. Eigentlich müssten doch irgendwann alles da sein und die Bedingung vom IF zutreffen.

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.

Net7 5. Nov 2005 15:16

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

fran 5. Nov 2005 16:20

Re: Problem mit case-of Anweisung in ClientSocket1Read
 
Zitat:

Zitat von Net7
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

Das habe ich schon probiert und es klappt natürlich. Ist zwar nicht ganz das was ich eigentlich vorhatte, aber ein guter Ersatz. Damit kann ich leben :-D

marabu 5. Nov 2005 16:28

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

fran 5. Nov 2005 17:13

Re: Problem mit case-of Anweisung in ClientSocket1Read
 
Zitat:

Zitat von marabu
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?

Wahrscheinlich nicht, aber da ich noch am Testen bin, habe ich einfach mal einen nicht zu niedrigen Wert genommen. Den Wert werde ich dann später allerdings sicher noch nach unten anpassen.

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:

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
Ich habe zwar schon hin und wieder kleine Progrämmchen mit Delphi geschrieben, aber da ich auf dem Gebiet von Sockets neu bin, weiß ich natürlich noch nicht was da so üblich ist und geschweige denn wie sowas geht.

CU Fran

marabu 5. Nov 2005 18:51

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.
Seite 1 von 2  1 2      

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