AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Problem mit case-of Anweisung in ClientSocket1Read

Problem mit case-of Anweisung in ClientSocket1Read

Ein Thema von fran · begonnen am 4. Nov 2005 · letzter Beitrag vom 5. Nov 2005
Antwort Antwort
Seite 1 von 2  1 2   
fran

Registriert seit: 4. Nov 2005
38 Beiträge
 
Delphi 6 Personal
 
#1

Problem mit case-of Anweisung in ClientSocket1Read

  Alt 4. Nov 2005, 20:10
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
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 4. Nov 2005, 20:28
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!
  Mit Zitat antworten Zitat
fran

Registriert seit: 4. Nov 2005
38 Beiträge
 
Delphi 6 Personal
 
#3

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 4. Nov 2005, 20:39
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.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 08:42
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;
  Mit Zitat antworten Zitat
fran

Registriert seit: 4. Nov 2005
38 Beiträge
 
Delphi 6 Personal
 
#5

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 15:17
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.
  Mit Zitat antworten Zitat
Benutzerbild von Net7
Net7

Registriert seit: 22. Jun 2004
Ort: Lauenburg
161 Beiträge
 
Delphi 7 Professional
 
#6

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 16:16
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
Marko
So`ne Atombombe kann einem den ganzen Tag verderben!
Eine eigene DLL in C++ geschrieben wird meist ein Sklave für mein Delphi/Pascal.
  Mit Zitat antworten Zitat
fran

Registriert seit: 4. Nov 2005
38 Beiträge
 
Delphi 6 Personal
 
#7

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 17:20
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
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#8

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 17:28
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
  Mit Zitat antworten Zitat
fran

Registriert seit: 4. Nov 2005
38 Beiträge
 
Delphi 6 Personal
 
#9

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 18:13
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
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#10

Re: Problem mit case-of Anweisung in ClientSocket1Read

  Alt 5. Nov 2005, 19:51
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
Angehängte Dateien
Dateityp: pas rngbuf_643.pas (1,7 KB, 19x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 15:30 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