Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem (https://www.delphipraxis.net/152080-tidtcpclient-writeln-tencoding-tidtextencoding-problem.html)

x000x 10. Jun 2010 12:10

TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Moin moin,

ich bin gerade dabei, ein Projekt von D5 (Indy 9.0.14) zu D2010 (Indy 10.5.5) zu portieren.

Zur Erklärung:
Ein TCPClient verbindet sich mit einem TCPServer - hierbei wird ein dynamisches Passwort zur
Authentifizierung verwendet/generiert. Dieses Pwd wird auch von Server generiert und dann mit
dem vom Client geschicktem Pwd verglichen => Authentifiziert/Nicht Authentifiziert.

Bei der Umstellung auf D2010 bin ich nun auf folgendes Problem gestossen (Der Server wird nicht geändert):

Delphi-Quellcode:
// Delphi 5
var
   szStr : String;
begin
   //..
   szStr := GenerierePwd(daten);
   // szStr := 'ABC' + #146 + 'DEF';
   WriteLn(szStr);
   // Am Server komt an: 'ABC' + #146 + 'DEF'
   //..
   
// Delphi 2010   
var
   szStr : AnsiString;
begin
   //...
   szStr := GenerierePwd(daten);
   // szStr := 'ABC' + #146 + 'DEF';
   Socket.WriteLn(String(szStr));
   // Am Server komt an: 'ABC' + #39 + 'DEF'
   //..
Wenn das vom Client generierte Passwort Zeichen wie #146 etc. enthält, dann kommt am Server - bei dem Beispiel mit #146 -
ein #39 an, womit der Server jetzt keine Übereinstimmung der Passwörter mehr findet.

Der "Fehler" musste also beim WriteLn liegen - also mal den Debugger angeschmissen und siehe da, folgendes konnte ich finden:

Delphi-Quellcode:
uses IdGlobal;
//..
var
   strTest : AnsiString;
   a, b : TIdBytes;
begin
   strTest := 'ABC' + #146 + 'DEF';
   a := ToBytes(String(strTest), -1, 1); // a[3] = #39
   b := ToBytes(String(strTest), -1, 1, TIdTextEncoding.Default); // b[3] = #146
d.h. jetzt für mich, dass ich beim WriteLn noch das Encoding mit angeben muss.

Delphi-Quellcode:
   //..
   Socket.WriteLn(String(szStr), TIdTextEncoding.Default);
   //..
Was ich hier jetzt nicht wirklich verstehe - es funktioniert wirklich nur mit TIdTextEncoding.Default.
Mit TIdTextEncoding.ASCII usw. habe ich es auch versucht - dort kommen dann aber nur "falsche" Ergebnisse raus.

Dieses Default hört sich für mich so System-abhängig an - wie kann ich hier sicher sein, dass es auf anderen Systemen ebenfalls
korrekt funktioniert?!

Zacherl 10. Jun 2010 13:27

AW: TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Das wirst du wohl testen müssen. Vielleicht ist das Default Encoding aber auch ein Äquivalent zum RawByteString also praktisch ein Byte Array.

x000x 10. Jun 2010 14:04

AW: TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Naja, insgeheim hoffe ich ja noch darauf, dass Assertor sich dazu nochmal äußert.
Auch verstehe ich nicht, warum es mit TIdTextEncoding.ASCII nicht funktioniert und dabei aus einem #146 ein #39 gemacht wird.

Zacherl 10. Jun 2010 15:20

AW: TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Benutzt du ein Unicode Delphi? Eventuell ist dies die Fehlerquelle.

x000x 10. Jun 2010 16:02

AW: TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Zitat:

Zitat von Zacherl (Beitrag 1027862)
Benutzt du ein Unicode Delphi? Eventuell ist dies die Fehlerquelle.

Ja, Delphi 2010. Wie schon gesagt, portiere ich ein Projekt von Delphi 5 nach Delphi 2010 und dabei
ist mir dieses Problem "unter gekommen"

In Delphi 5 / Indy 9.0.14 gab es die Funktion ToBytes bzw. den Typen TIdBytes noch nicht.

Nur wie schickt man dann richtig einen String an den Server (mit Delphi 2010)?

Mit Delphi 5 wurde es so gemacht:
Delphi-Quellcode:
//..
IdTCPClient.WriteLn(strPwd);
und mit Delphi 2010 funktioniert es nur hiermit:
Delphi-Quellcode:
//..
IdTCPClient.Socket.WriteLn(String(strPwd), TIdTextEncoding.Default);
Eventuell müssen ja nur die Routinen die Strings verschickt haben, in D2010 ByteArrays verschicken?!

Wie gesagt, mit der Angabe vom Encoding funktioniert es hier - nur verstehe ich halt nicht wirklich, warum es mit TIdTextEncoding.ASCII nicht funktioniert.
[Nachtrag]
Weil ASCII Zeichensatz nur bis 127 :oops:
[/Nachtrag]

Assertor 11. Jun 2010 11:12

AW: TIdTCPClient / WriteLn / TEncoding / TIdTextEncoding Problem
 
Hallo Peter,

Dein Ansatz ist soweit ich sehen kann richtig. TIdTextEncoding.ASCII ist nur 7 bit, also nur bis 127. TIdTextEncoding.Default nutzt die Default CodePage des Betriebssystems.

Gruß,
Assertor


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