![]() |
Indy Record sendeproblem
Hi Leute,
ich habe eine Problem mit Indy(ka welches es ist, aufjedenfall das was bei Delphi 6 pro standart drauf ist). Nun gut ich möchte verschiedene Records senden, welche ich vorher mit einer Zahl ankündige, damit der Server die richtigen Dinge ausführt. Hier das Servererigniss vom Server
Delphi-Quellcode:
und hier bei der Zeile bleibt er stehen(1.)
Procedure TFormSockel.IdTCPServer1Execute(AThread: TIdPeerThread);
var anweisung: byte; begin anweisung:= AThread.Connection.ReadSmallInt; case anweisung of 2: IdentifikationsAnfragen(AThread); end; end;
Delphi-Quellcode:
auf dem Client findet sich das hier:
procedure IdentifikationsAnfragen(AThread: TIdPeerThread);
var vuser: TIdentifikationMSG; vplatz: byte; vantwort: TIdentifikationAntwort; vip : string; begin AThread.Connection.ReadBuffer(vuser,sizeof(TIdentifikationMSG)); vip:=AThread.Connection.Binding.PeerIP; vplatz:= istnochplatz; vantwort.userid:=0; //grundwerte vantwort.voll:= false; vantwort.nicvergeben:= false; If(vplatz = 0) then //voll? vantwort.voll:= true else begin if(nicktest(vuser.nickname) = true) then //Nickname testen begin vantwort.nicvergeben:= true; end; end; ......
Delphi-Quellcode:
Ich hoffe ihr könnte mir helfen. Wollte es am Dienstag vorstellen, nur leider scheitert es schon hier.
procedure handschake;
var vselfid : TIdentifikationMSG; antwort: TIdentifikationAntwort; begin with Formhintergrund.IdTCPClient1 do begin Connect; try begin WriteSmallInt(2);// TIdentifikationMSG vselfid.nickname:= FormVerbinden.EditNickname.Text; WriteBuffer (vselfid,sizeof(vselfid));//senden end; except showmessage('Konnte nicht verbinden'); exit; end; end; end; Danke im Vorraus mfg Lukas |
Re: Indy Record sendeproblem
Zitat:
Ubd wie ist TIdentifikationMSG aufgebaut? Sind dynamische Felder enthalten? |
Re: Indy Record sendeproblem
Oh sorry meinte
Delphi-Quellcode:
Bei dieser Zeile bleibt der debugger stehen, ohne Fehlermeldung oder sonst etwas der gleichen.
AThread.Connection.ReadBuffer(vuser,sizeof(TIdentifikationMSG));
Hier die Typen:
Delphi-Quellcode:
hoffe das hilft weiter :(
type
TIdentifikationMSG = record nickname: string; end; type TIdentifikationAntwort = record userid: byte; voll: boolean; nicvergeben: boolean; end; |
Re: Indy Record sendeproblem
Ok. Dann hätte ich einen Fehler gefunden. Aber eigentlich hätte die Exception bei dem Fehler etwas später kommen sollen.
Du kannst nicht einen String so übergeben. Das gilt für ReadBuffer genauso wie für Writebuffer. Nimm besser ReadString und WriteString. |
Re: Indy Record sendeproblem
Das Problem sehe ich nur, das der Server das nicht mehr richtig zugeordnet bekommt bzw mir nicht einfällt wie ich das lösen könnte, da in manchen Fällen, wie beim Chat der Nutzer,(bei mir durch ID gekennzeichnet), einen String beim Nachrichtenschreiben übergeben muss.Konkret meine das mit String diese Typen betreffen:
Delphi-Quellcode:
Die letzten beiden dienen zur Richtungsangabe. Die anderen für eine bessere Erkennung wer und wo ein Spiel eröffnet.type TChatNachricht = record // userid: byte; nachricht:string; end; type TIdentifikationMSG = record nickname: string; end; type TSpielopenantwortlogin = record serverid : byte; servername : string; end; type TSpielerguckanders = record userid : byte; richtung: string[2]; end; Type TBomberutscht = record Bombenid : byte; Richtung : string[2]; end; |
Re: Indy Record sendeproblem
Habe ich mir fast gedacht. Ich wollts noch erwähnen. Um es nochmal zusammenzufassen. Du kannst so nur statische Records senden. Also Records in denen keine Ansistrings und keine dynamischen Arrays drin vorkommen (von Objekten etc. mal abgesehen). Allerdings funktionieren Shortstrings, so wie sie in TSpielerguckanders und TBomberutsch deklariert sind. Teste mal, ob die problemlos rüberkommen!
Das ist, wie gesagt definitiv ein Problem(/Fehler), aber es könnte nicht das einzigste sein. Wenn du einen string ohne Längenangabe deklarierst ist es eine dynamische Variable. Also während für z.B. string[100] direkt an der Stelle der Variablen (oder des Records) 100+1 Zeichen reserviert werden, wird bei einem dynamischen string immer 4 Bytes reserviert, welche einen Zeiger darstellen, auf einen Spiehcerplatz, wo dann wirklich der String steht (deswegen ist sizeof(TIdentifikationMSG) immer 4 Bytes). Und du kopierst nur diesen Zeiger. Das losschicken des Zeigers ist kein Problem, auch wenn die Information sinnlos ist. nur bei Readbuffer überschreibst du einen String-Zeiger, der damit ungültig wird und irgendwohin zeigt. Das pringt eben einen Fehler. Allerdings verstehe ich nicht, der Fehler dürfte erst beim nächtsen Zugriff auf vuser kommen. Naja, mal probieren. |
Re: Indy Record sendeproblem
Hey danke daran hat es gelegen. Habe einfach alle Strings mit [] versehen und schon gings. Hm musste mir irgendwie klar sein das 2 Gb etwas zu groß sind^^. Danke für die Hilfe!! Ihr seit die Besten. :hello:
mfg Lukas |
Re: Indy Record sendeproblem
Bitte, aber ich will dir noch kurz die Nachteile von Shortstrings (bzw. Strings mit Längenangabe) sagen:
-solche Shortstrings können maximal 255 Zeichen aufnehmen -Sie benutzen immer den vollständigen Platz (in der Länge, wie sie deklariert sind + 1) egal wie lang der eigentliche String ist. Das ist eben auch wichtig beim Senden über Sockets. Dadurch kann das Paket unnötig groß werden -Du musst dich eben auf eine Maximallänge festlegen. Ich könnte mir aber vorstellen, dass es bei dir kein Problem darstellt. |
Re: Indy Record sendeproblem
Hast schon recht, allerdings sind diese bei mir maximal auf 15 gesetzt und somit finde ich bei 8 Clients pro Server tragbar. Aber danke noch mal für die Info.
|
Re: Indy Record sendeproblem
Hallo Leute ich bins nochmal,
ich bin nun zu einen seltsamen Problem gekommen. Die verbindung zum Server steht allerdings kann der Server mit einer Indy-client-komponente antworten senden. Beim Connect bekomm ich einen Sockel #10049 fehler.
Delphi-Quellcode:
Dazu ist zu sagen, das der client(TidTcpclient) in einen anderen Unterprogramm zugewiesen wurde.
procedure antwortsendenId(client: TidTcpclient; antwort:TIdentifikationAntwort; ip:string);
begin with client do begin Port:= 6667; BoundIP:= ip; Connect; try client.WriteSmallInt(3); client.WriteBuffer(antwort,sizeof(TIdentifikationAntwort)); finally If(antwort.userid = 0) or (antwort.nicvergeben = true) then Disconnect; end; end; end; Desweiteren finde ich es sehr seltsam, das ich bei meinen Client.exe die Client-Komponenten mit einem activate setzten kann, beim Server nicht:
Delphi-Quellcode:
Hoffe sirius oder andere können mir helfenwith Formhintergrund.IdTCPClient1 do begin Activate; Host:= EditIPaddresse.Text; Port:= 6666; end; .... mfg Lukas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:07 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