![]() |
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:
Das Programm kann fehlerfrei compiliert werden, doch wenn der delay von timer2 zuende ist, wird das Programm mit einem Fehler abgebrochen.
//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; Danke für jegliche Hilfe. Ciao Crayser |
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 |
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. |
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 |
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. |
Code:
Hallo Christian,
temp[i-1]:=empfang[i];
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. |
Mit welchem Wert beginnt die Schleife denn? Nach dem, was du geschriebenn hast, müsste sie mit i=2 beginnen.
|
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. |
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. |
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. |
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. |
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:
als Trennzeichen nutze ich einfach a.
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; 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 |
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:
Hier nun die Werte, die der Debugger mir ausspuckt, nachdem ich die :
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; 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