Autor Beitrag
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Mi 18.05.11 13:25 
Hallo ich habe mein D6 Projekt auf D2010 umgestellt und das ganze funktioniert nur halb.

Ich glaube das Problem ist folgendes:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function TCustomWinSocket.SendText(const s: String): Integer;
begin
  Result := SendBuf(Pointer(S)^, Length(S) * SizeOf(Char));
end;


Da user profile iconMartok vorhin erwähnt hat das ein Unicodezeichen nicht immer 2 Byte belegt stellt sich mir die Frage ob man das überhaupt mit einem Widechar wie oben berechnen kann.

Fakt ist die Daten kommen auf der anderen Seite an allerdings nur fehlerhaft.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 18.05.11 14:15 
Moin!

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo ich habe mein D6 Projekt auf D2010 umgestellt
In diesem Fall solltest du alle Strings, die über´s Netz gehen, als AnsiString deklarieren und String-Parameter in utf8 konvertieren. Das ist IMHO der Beste Ansatz für so eine Umstellung. :idea:

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Ich glaube das Problem ist folgendes:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function TCustomWinSocket.SendText(const s: String): Integer;
begin
  Result := SendBuf(Pointer(S)^, Length(S) * SizeOf(Char));
end;
Wo hast du das Code-Stück her? Grundsätzlich nicht "schön", aber unter D2010 IMHO OK.

Das bei Strings mit einer Datenmenge >8KB dieser String bei .ReceiveText() nicht wieder "an einem Stück raus" kommt, ist dir aber bekannt?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: thepaine91
thepaine91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Mi 18.05.11 14:34 
Narses hat folgendes geschrieben:
In diesem Fall solltest du alle Strings, die über´s Netz gehen, als AnsiString deklarieren und String-Parameter in utf8 konvertieren. Das ist IMHO der Beste Ansatz für so eine Umstellung. :idea:

Okay das ist schon mal ein Ansatz (so sah es auch vor meiner Änderung aus... -.-*) :oops: .
Narses hat folgendes geschrieben:

Wo hast du das Code-Stück her? Grundsätzlich nicht "schön", aber unter D2010 IMHO OK.

Das Codestück ist aus der Unit ScktComp aus D2010, hab mir das abgeleitet und umgeschrieben.
Narses hat folgendes geschrieben:

Das bei Strings mit einer Datenmenge >8KB dieser String bei .ReceiveText() nicht wieder "an einem Stück raus" kommt, ist dir aber bekannt?

Ja ist mir bekannt die Basis des Programms kommt auch aus deinem Tutorial. ;)


EDIT:
Ach so sieht übrigens ReceiveText aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
function TCustomWinSocket.ReceiveText: String;
begin
  SetLength(Result, ReceiveBuf(Pointer(nil)^, -1));
  SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;

(Daran habe ich nichts verändert.)
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 18.05.11 16:26 
Moin!

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Ach so sieht übrigens ReceiveText aus:
ausblenden Delphi-Quelltext
1:
function TCustomWinSocket.ReceiveText: String;					
(Daran habe ich nichts verändert.)
Da steht ernsthaft im Original String?!? :shock: Da muss unbedingt ein AnsiString hin, der "Fehler" (stammt aus D2009) sollte doch eigentlich in D2010 wieder raus sein... :gruebel: (die ScktComp-Sockets sind auf AnsiString ausgelegt und kriegen auch nix anderes auf die Kette; das hat nix mit der WSA zu tun, sondern mit dem Design der Kompos, ist halt so)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: thepaine91
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 19.05.11 06:40 
In Delphi XE steht da wieder AnsiString.

Allerdings funktioniert es auch problemlos mit Unicodezeichen... ja, wenn man es denn richtig macht. Der gepostete Quelltext von ReceiveText ist schlicht falsch...
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
function TCustomWinSocket.ReceiveText: String;
begin
  SetLength(Result, ReceiveBuf(Pointer(nil)^, -1)); // Die Länge wird auf die Anzahl Byte gesetzt
  SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result)));
end;
Wenn man das richtig macht, funktioniert es zumindest bei XE absolut problemlos mit Unicode, ich habe diverse Tests gemacht. Hier mal ein Fix:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
type
  TUnicodeCustomWinSocketHelper = class helper for TCustomWinSocket
  public
    function SendUnicodeText(const Value: String): Integer;
    function ReceiveUnicodeText: String;
  end;

{ TUnicodeCustomWinSocketHelper }

function TUnicodeCustomWinSocketHelper.ReceiveUnicodeText: String;
begin
  SetLength(Result, ReceiveBuf(Pointer(nil)^, -1div SizeOf(Char));
  SetLength(Result, ReceiveBuf(Pointer(Result)^, Length(Result) * SizeOf(Char)) div SizeOf(Char));
end;

function TUnicodeCustomWinSocketHelper.SendUnicodeText(const Value: String): Integer;
begin
  Result := SendBuf(Pointer(Value)^, Length(Value) * SizeOf(Char));
end;
Was in dem Originalquelltext nämlich nicht beachtet wird, ist dass auch beim Empfang ein Zeichen nun einmal nicht ein Byte hat.

Statt das also wieder auf AnsiString zu setzen, hätten sie es besser dort richtig korrigiert...
Mit SendBuf und ReceiveBuf funktioniert es hier jedenfalls problemlos. Ich habe gerade diverse Unicodetexte geschickt, es gab keinerlei Probleme:

SocketUnicodeReceived
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: thepaine91
thepaine91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 19.05.11 08:55 
Danke für eure Hilfe, @Jaenicke dann werde ich das mal abändern. Finde es auch schöner gleich Unicode zu verschicken als x mal zu konvertieren.

Edit:
So es funktioniert nun Einwandfrei :) :D :dance2: :dunce: :nut:

Aber Kopieren kann ja jeder daher versuche ich die Änderung zu verstehen.

Also so verstehe ich es:

Ansistring der Länge 3 = 3 Byte;
Widestring der Länge 3 = 6 Byte;

Da ReceiveBuf die Anzahl der tatsächlich gelesenen Bytes zurück gibt, wird Result dann auf 6 anstatt auf 3 gesetzt und das hast du mit div SizeOf(Char) geändert. Richtig?

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Hoffe das gilt nicht als Schiebung? (Da es ja ein neuer Abschnitt zum Thema ist) Falls doch bitte ich um Entschuldigung.

Ich steht nun vor dem Problem die gesamte Kommunikation zwischen den beteiligten zu verschlüsseln. Das Verschlüsseln ist dabei nicht das Problem sondern das die Daten nicht an einem Stück beim empfänger ankommen müssen. Entsprechend funktioniert das dann natürlich nicht.

(TCP)
Meine einzige Idee ist die verschlüsselten Daten in gesondertes Tags ein zu betten. (Sowas wie [Encoded] ^^)
Aber toll finde ich das jetzt auch nicht...

Lieber wäre mir das ich die Pakete selbst verwalte und diese verschlüssel. Da dies aber von Windoof verwaltet wird sollte das schwierig werden.....

Hat also jemand eine bessere Idee?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 19.05.11 12:24 
Moin!

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Ich steht nun vor dem Problem die gesamte Kommunikation zwischen den beteiligten zu verschlüsseln. Das Verschlüsseln ist dabei nicht das Problem sondern das die Daten nicht an einem Stück beim empfänger ankommen müssen. Entsprechend funktioniert das dann natürlich nicht.

(TCP)
Also wie jetzt, du hast eine TCP-Verbindung, aber die Daten kommen nicht korrekt an?! :gruebel:

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Hat also jemand eine bessere Idee?
Die Verschlüsselung auf Transport-Layer-Ebene umsetzen, hier habe ich sowas schonmal gemacht. (evtl. auch mal ein paar Beiträge vorher/nachher lesen) :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: thepaine91
thepaine91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 19.05.11 13:10 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Ich steht nun vor dem Problem die gesamte Kommunikation zwischen den beteiligten zu verschlüsseln. Das Verschlüsseln ist dabei nicht das Problem sondern das die Daten nicht an einem Stück beim empfänger ankommen müssen. Entsprechend funktioniert das dann natürlich nicht.

Also wie jetzt, du hast eine TCP-Verbindung, aber die Daten kommen nicht korrekt an?! :gruebel:

Nein ich wollte damit sagen das ich es mit der Socketkomponente nicht in der Hand hab wie die Daten gestückelt werden. Und somit meine Daten nicht komplett verschlüsseln kann.

user profile iconNarses hat folgendes geschrieben:

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Hat also jemand eine bessere Idee?
Die Verschlüsselung auf Transport-Layer-Ebene umsetzen, hier habe ich sowas schonmal gemacht. (evtl. auch mal ein paar Beiträge vorher/nachher lesen) :idea: ;)

Genau so etwas habe ich gesucht wusste nur nicht wie ich das angehen soll.
Danke sollte mir erst mal als Stoff genügen.
thepaine91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Fr 20.05.11 09:43 
Da ich atm nicht so viel Zeit habe musste ich das ganze schnell Programmieren.

Naja daher hab ich jetzt einfach eine 2. Protokollebene, die nur auf Vollständigkeit eines Datensatzes prüft, eingefügt. Sobald der Datensatz Vollständig ist wird er Decoded und Fertig. Encoden tut der Socket und Decoden der Parser des Protokolls.

Nicht schön aber ging schnell und funktioniert. ^^