Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Daten synchronisieren (https://www.delphipraxis.net/2356-daten-synchronisieren.html)

Crayser 19. Jan 2003 16:28


Daten synchronisieren
 
Hallo zusammen
ich habe 2 programme; server und client. nun will ich das der server nach einer gewissen zeit einige Variablen zum Client sendet.

Code:
//Code vom Server
procedure TForm1.Timer2Timer(Sender: TObject);
var Leftstr:string;
begin
Leftstr:=inttostr(Schlaeger.Left);
ServerSocket1.Socket.Connections[0].SendText('4'+Leftstr);

//Code vom Client
empfang := ClientSocket1.Socket.ReceiveText; //client empfängt
choose:= strToInt(empfang[1]);

case choose of
1: ..
2: ..
3: ..
4: begin for i:=2 to length(empfang) do
         temp[i-1]:=empfang[i];
      SchlaegerKopf.Left:=strtoint(temp);
   end;
Das Programm kann fehlerfrei compiliert werden, doch wenn der delay von timer2 zuende ist, wird das Programm mit einem Fehler abgebrochen.

Danke für jegliche Hilfe.
Ciao Crayser

Crayser 20. Jan 2003 15:21

Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe noch die Fehlermeldung in den Anhang gesetzt. Kann mir jemand sagen was da nicht stimmen könnte?
Wenn ihr wollt, kann ich die source vom client und server noch uploaden. Doch an anderen Stellen im source dürfte der Fehler nicht liegen.

ciao Crayser

Christian Seehase 22. Jan 2003 19:59

Moin Crayser,

möglicherweise tritt der Fehler auf, beim Zugriff auf empfang[1].
Nachdem ReceiveText ausgeführt wurde, solltest Du, sicherheitshalber, prüfen, ob empfang überhaupt Daten enthält.

Ich weiss jetzt zwar nicht, wie gross das Intervall bei Deinem Timer2 ist, aber es könnte sinnvoll sein, die Routine mit einem Timer2.Enabled := false zu beginnen, und mit einem Timer2.Enabled := true zu beenden, damit sich verschiedene Timeraufrufe nicht gegenseitig überholen.

Crayser 24. Jan 2003 16:50

Kein Erfolg
 
Hi Christian

die Fehler liegen nicht an den anderen case Befehlen. Der case Befehl ist eigentlich aus if empfang=1 .. else if empfang=2 .. etc. audgebaut. Deshalb sind die Anweisungen unabhängig voneinander. Bei den 3 anderen case Befehlen läuft alles gut.

Timer2 ist nicht sehr lang; habe es trotzdem mit dem dis/enable probiert.. ohne Erfolg. Trotzdem Danke. Das timing Intervall ist auch sehr lang (macht keinen Unterschied in welchen Zeitabständen der timer aufgerufen wird).
Wie gesagt wenn du willst, kann ich den ganzen code uploaden doch ist er noch nicht fertig, da ich noch einige andere Sachen vorschieben muss. Das Programm(ist übrigens nen Spiel) ist trotzdem startbar.

ciao Crayser

Christian Seehase 24. Jan 2003 18:17

Moin Crayser,

geh' doch mal im Einzelschritt durch das Programm (F7/F8) und versuch' mal dadurch die Fehler erzeugende Stelle zu finden.
Am Besten vor der verdächtigen Stelle einen Breakpoint setzen, und dann weiter im Einzelschritt.

Crayser 25. Jan 2003 10:48

Code:
 temp[i-1]:=empfang[i];
Hallo Christian,
beim debuggen bleibt er an diesem code hängen. ich persönlich kann da aber keinen fehler erkennen. beide variablen sind strings, ich kopiere bis auf das erste zeichen den ganzen inhalt von empfang in temp. i ist in einer for schleife die bis length(empfang) läuft.

Chewie 25. Jan 2003 11:02

Mit welchem Wert beginnt die Schleife denn? Nach dem, was du geschriebenn hast, müsste sie mit i=2 beginnen.

Crayser 25. Jan 2003 14:48

Ah ich hab den Fehler gefunden. Ich hatte die Größe der strings nicht deklariert und daher kam der Fehler. Jetzt ist es aber nun ziemlich unpraktischt, da ich das Ende von temp bestimmen muss. Je nachdem wie groß der integerwert von empfang ist, variiert das ende von temp. Gibt es da einen eleganteren Weg, als alle (bzw. die Endwerte) von temp vorher auf #0 zu setzen?
Danke für die Tipps Christian.

ja die Schleife hängt mit i=2 an, da bei empfang[1] nur der Wert für die case Anweisung ist bei i=2 bis ende hab ich dann die info, die der server an den clienten weitergeben soll.

Christian Seehase 25. Jan 2003 18:04

Moin Crayser,

hast Du jetzt temp : string[...] deklariert?
Das wäre dann ein ShortString.

Die Länge initalisieren ginge, z.B., mit SetLength, oder auch einer Zuweisung von StringOfChar.
Wie gross temp dabei wird kannst Du dann ja anhand der Länge von empfang festlegen.

Crayser 3. Feb 2003 11:38

Hallo Christian
wird dann die Länge des Strings dynamisch geregelt? Also kann ich dann getrost die Auffüllung mit #0 weglassen wenn ich die Länge mit SetLength deklariere? Muss ich mal ausprobieren.

Nun hab ich aber ein anderes Problem, wo ich noch nicht so schnell eine Lösung finden konnte. Und zwar will ich gleich mehrere Informationen aufeinmal per Netzwerk senden. Jedoch ist sendText bzw. ReceiveText (ich weiss nicht genau welche die Probleme bereitet) bei mehreren Aufrufen hintereinander ziemlich problematisch, da (ich vermute) die case Anweisung noch nicht zuende gearbeitet werden konnte bevor der Client schon eine neue Anweisung erhält.
Da dachte ich mir ich sende gleich alle Informationen auf einmal in einem String. Was mein Problem ist könnt ihr euch ja denken. Wie kann ich die Befehlsinformationen auseinanderhalten (bzw. unterscheiden wo das Ende und wo der Anfang der nächsten Information ist). Die Länge variiert.

Deshalb bringt mir ..SendText(Info1+Info2+..) nichts, da ich nicht genau weiss ab wann/wo die zB Info2 beginnt. Ich dachte mir das man irgendwelche speziellen Zeichen als Indikator für das Ende der Strings machen könnte doch weiss ich nicht wie ich es ins Programm umsetzen kann. Habt ihr/hast du eine Idee?

Ciao Crayser

P.S.: Sorry, das ich so lange nicht zurückgeschrieben hab, die Zeit ist bei mir im Moment ziemlich knapp.

Christian Seehase 3. Feb 2003 12:32

Moin Crayser,

als Trennzeichen kommt prinzipiell jedes Zeichen in Frage, das nicht in Infox vorkommen kan.

Auf Empfängerseite liesse sich dass den relativ leicht auseinanderfieseln, falls in den Infox Strings kein #13#10 vorkommt.

Dann könntest Du das Trennzeichen mittels StringReplace durch #13#10 ersetzen, und dann den gesamten String in eine Stringlist packen.
So hättest Du dann pro Zeile in der StringList einen Infox Wert.

Crayser 9. Feb 2003 12:56

Hallo Christian
erst einmal zur Länge des Strings.
ich habe es jetzt ziemlich unelegant gelösst. woher soll denn empfang die Länge erfahren? Soll ich die Information über die Länge des Strings schon im Clienten mitsenden, sodass empfang seine Größe mit dem gegebenen Wert verändern kann? Denn die Länge hängt ja von der Länge ab, die der Client versendet. Das gleiche Problem habe ich dann auch bei temp.
Am besten kann ich mit dem Codeabschnitt erklären.
Code:
case
...
4: begin
i:=2;
temp[2]:=#0;
temp[3]:=#0;
temp[4]:=#0;
temp[5]:=#0;
while empfang[i]<>'a' do
begin
  temp[i-1]:=empfang[i];
  inc(i);
end;
SchlaegerKopf.Left:=ClientWidth-Schlaeger.Width-strtoint(temp);
inc(i);
j:=1;
temp[2]:=#0;
temp[3]:=#0;
temp[4]:=#0;
temp[5]:=#0;

while empfang[i]<>'a' do
begin
  temp[j]:=empfang[i];
  inc(i);
  inc(j);
end;
als Trennzeichen nutze ich einfach a.
hier ist ein codeabschnitt vom case befehl. Wie kann ich die Länge von temp bestimmen damit ich nicht immer mit #0 ausfüllen muss. Denn wenn die Information von temp zB nur 3Zeichen hat muss auf temp[4] ein #0 sein bei 2Zeichen auf temp[3] etc.
Ich bin noch unerfahren wenn es um Stringlists geht. Könntest du mir zeigen wie ich mit denen umgehen kann? Oder gibt es bereits gute Beiträge irgendwo im Forum?
Jetzt zumindest braucht das Programm nicht mehr die 10 sek bis er abstütrzt sondern ca. 1min doch wodran das liegt weiss ich auch nicht.
Wahrscheinlich da ich nicht genau sagen kann wo das ende von empfang ist.

Ciao Crayser

Crayser 26. Feb 2003 19:45

Hallo zusammen,
mithilfe des debuggers habe ich eine seltsame Sache entdeckt. Und zwar handelt es sich um ein shortstring, den ich nicht editieren kann.

Hier nochmal ein aktuelles Code Fragment:
Code:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var empfang:string[26];
test:char;

temp,t1:string[5];
t2,t3,t4:string[5];
    j,i,choose:integer;

begin
empfang := ClientSocket1.Socket.ReceiveText; //client empfängt

choose:= strToInt(empfang[1]);

case choose of
..
4: begin
i:=2;

while empfang[i]<>'a' do //info wird von empfang[2] in temp[1]
//gespeichert, dann von empf.[3] in temp[2] usw. bis empfang[i]=a
begin
  temp[i-1]:=empfang[i];
  inc(i);
end;
temp[i]:=#0; //temp wird abgeschlossen..
SchlaegerKopf.Left:=ClientWidth-Schlaeger.Width-strtoint(temp);
//..und verarbeitet
inc(i); //i wird erhöht damit anschliessend empfang[i] nicht a ist
j:=1;

while empfang[i]<>'a' do //gleiche prozedure wird aufs neue durchlaufen
//wobei j wieder von anfang an zählt und i den inhalt aus empfang //durchläuft
begin

  t1[j]:=empfang[i];
  inc(i);
  inc(j);
end;
t1[j]:=#0;

Ball.Top:=ClientHeight-Ball.Height-strtoint(t1);
inc(i);
j:=1;

while empfang[i]<>'a' do
begin

  t2[j]:=empfang[i]; //**HIER IST DER FEHLER**
  inc(i);
  inc(j);
end;
t2[j]:=#0;

Ball.Left:=ClientWidth-Ball.Width-strtoint(t2);
..
end;
end;
Hier nun die Werte, die der Debugger mir ausspuckt, nachdem ich die :
empfang:'4280a400a334a0a-2a'
temp:'280'#0#0'r'#4'º280'#0#0#0#0'º280'#0#0#0#0'º2 80'#0#0'r'#4'º280'#0#0'r'#4'º280'#0#0'r'#4#0'3«'#2 '+'#0#0#0'1400'#0'«r'#4#$1A'¿'#3#0#0#0#0#0#0#0#0#0 #0#0#0#0'´¼·'#4'@'#0#0#0'äþ‘'#5#0#0#0#0#0#0'‘'#5#$ 1E'ù'#0#0#0#0#0#0#0#0#0#0'üŸå'#4'¤så'#4'äþ‘'#5#0#0 #0#0'§*'#1#0#$1C'*å'#4#$1C'¡å'#4'L¥r'#4'´¼·'#4'œš¿ '#4'¬þ‘'#5#$1A'©'#3#0#0#0#0#0'¬®r'#4#$C'*r'#4'¤så' #4'ô'#2#0#0'8…å'#4#0#0#0
t1:'400'#0'«r'#4#$12'4280a400a334a0a-2aÿÿÃ'#$1C'1w_:'#4'º280'#0#0'r'#4'º280'#0#0
t2:''

Wieso gibt es keine Werte in t2? Bedeutet dies, dass t2 nicht in den Stack geladen wird bzw. kein Platz dafür reserviert wird? Wenn ja, was kann ich dann machen?
Dabei ist es egal welche strings ich dafür nutze.. anstatt der 5 strings habe ich auch einen benutzt doch der fehler ist der gleiche.
Ausserdem kriege ich es nicht hin eine setlength anweisung für strings erfolgreich zu compilieren. Mit SetLength(String;strlänge); geht es nicht.
Irgendwelche Ideen?


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