![]() |
Indy TCP Server - Record versenden ?!
Hallo Leute.
Ich verstehe nicht wie ich ein Record mit der Indy TCP Server Komponente versenden kann, und wie ich es auf der anderen Seite annehmen kann. Mein Record sieht so aus:
Delphi-Quellcode:
und So versuche ich zu senden:
TConnectionData = record
Command: string; Typ: string; ParamCount: integer; Param: array [0..9] of string; end;
Delphi-Quellcode:
Und der Compiler sagt dazu ällabätsch:
// Willkommensmeldung senden
Data.Command := 'SERVER_SAY_WELCOME'; Data.Typ := 'NOANSWER'; Data.ParamCount := 0; ClientInf.Thread.Connection.IOHandler.Write(Data, SizeOf(TConnectionData)); // --- Zitat:
Kann mir mal bitte jemand einen Tipp geben? Ich glaube es werden bei Strings sowieso nur Zeiger übertragen, oder? Das hilft mir so wie ich es gemacht habe nicht richtig weiter. Danke... |
AW: Indy TCP Server - Record versenden ?!
|
AW: Indy TCP Server - Record versenden ?!
Guten Abend,
es hat jetzt nicht direkt etwas mit Deinem Problem zu tun, aber ..
Delphi-Quellcode:
Mit Delphi >= 2009 ist ein String ein UniCode-String.
TConnectionData = record
Command: string; Typ: string; ParamCount: integer; Param: array [0..9] of string; end; Ein UniCode-String ist ein Pointer der auf einen Speicherblock zeigt in dem die Zeichen liegen. Wenn Du diese Record verschickst, werden nur die Pointer-Adressen verschickt. Der Empfänger kann in der Regel nichts damit anfangen.
Delphi-Quellcode:
So werden wieder shortStrings verwendet
TConnectionData = packed record
Command: string[128]; Typ: string[128]; ParamCount: integer; Param: array [0..9] of string[64]; end; Grüße Klaus |
AW: Indy TCP Server - Record versenden ?!
Zitat:
Da lohnt es sich, über den Tellerrand zu schauen und zu kucken wie andere das machen. Zunächst mal haben deine Records/Befehle potentiell eine unterschiedliche Länge und man muss besondere Maßnahmen treffen um das Ende der Record zu erkennen. Viele Internetprotokolle wie z.B. SMTP, POP3, FTP sind so aufgebaut, dass man einen Befehl der mit CRLF abgeschlossen schickt und der Server mit einem OK oder einer Fehlernummer antwortet. Die Protokolle sind für einen Menschen lesbar und man kann sie mit Telnet simulieren, was besonders zum Debuggen nützlich ist. Das Ende eines Befehls oder einer Antwort lässt sich also immer am CRLF erkennen. Deine Records/Befehle könnten also so übertragen werden:
Code:
Hier einige Beispiele, damit man sich das besser vorstellen kann:
COMMAND,Param1,Param2,Param3,...<CRLF>
Code:
Parameter die ein Komma enthalten müssen in Hochkomma eingeschlossen werden.
LOGON,user7,geheim<CRLF>
GETSTATUS<CRLF> STARTEXE,C:\Windows\notepad.exe,C:\Windows,0<CRLF> SHOWMSG,Das ist die Caption,'mit einem Text, der ein Komma enthält'<CRLF> SLEEP,5000<CRLF> |
AW: Indy TCP Server - Record versenden ?!
Ich hab es nun mit dem packed Record versucht, und das scheint erstmal zu funktionieren. Aber es ließt sich nicht als optimale Lösung.
|
AW: Indy TCP Server - Record versenden ?!
siehe beitrag
![]() Zitat:
![]() Dein Protokoll ist doch jetzt auch schon textbasiert - oder was steht in den Strings. ShortString sind besser geeignet weil sie anders aufgebaut sind: ShortString [0]-Länge des Strings [1...length-1] Inhalt String : Pointer auf Speicher in dem der Inhalt steht. Mit pointern kann der Empfänger nichts anfangen, weil diese nur auf Deinem System gültig sind. Beim Empfänger können sie ins Nirvana zeigen - daher wahrscheinlich auch die Exceptions. Grüße Klaus |
AW: Indy TCP Server - Record versenden ?!
falls das thema noch aktuelle ist ?
unter source forge demo indy 10 habe ich mehrer komplette lösungen eingestellt |
AW: Indy TCP Server - Record versenden ?!
Zitat:
![]() Das Problem ist nur, dass deine Demos nicht sauber trennen zwischen Datenaufbereitung (Protokoll) und Datentransport (TCP/IP). Leider hat diesbezüglich Indy selbst grosse Designfehler. Nehmen wir z.B. die Klasse TIdSmtp als Umsetzung des SMTP-Protokolls. Gibt es aus Sicht von SMTP einen Unterschied zwischen TCP, Named Pipes oder Serieller Schnittstelle? Antwort: Nein, sobald TCP, Named Pipes oder ser. Port geöffnet sind verhalten sie sich gleich. Man kann Daten lesen und Daten schreiben; es ist ganz einfach ein bidirektionaler Stream. Man hätte der Klasse TIdSmtp also über ein Property von Aussen diesen bidirektionaler Stream geben sollen. Somit wäre es egal ob sich dahinter TCP/IP, ![]() Stattdessen hat man aber eine sehr tiefe Klassenhierachie geschaffen:
Code:
Hier kann man als Analogie auch die Klassen TQuery, TDataSource und TDBGrid hernehmen.
TIdSmtp <- TIdSmtpBase <- TIdMessageClient <- TIdExplicitTLSClient <- TIdTCPClientCustom <- TIdTCPConnection <- TIdComponent <- TIdBaseComponent <- TIdInitializerComponent <- TIdNativComponent
Dem DBGrid ist es egal vorher die Daten kommen und wohin sie geschrieben werden. Genau so hätte auch Indy designed werden müssen (der kleine Nachteil ist, dass man so 3 statt nur einer Komponente braucht) . Daher: das Protokoll aus Anwendungsebene (OSI Level 7) muss unbedingt vom Datentransport getrennt gehalten werden! Versuche doch einfach mal deine Demos so umzubauen, dass man sie wahlweise mit Indy oder mit der Unit ScktComp benützen kann (aber ohne Code zu duplizieren). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:51 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