Schwedenbitter - Mi 07.12.16 12:03
Titel: AnsiString mit Indys senden
Hallo,
zunächst möchte ich mich bei Narses für dessen
super Anleitungen [
https://www.entwickler-ecke.de/topic_66706.html] bzgl. Netzwerkkommunikation bedanken. Ich nutze eine aufgebohrte Version auf einem Linux-Server. Leider nutzen die Sockets von Borland die VCL, so dass ich eine VM mit Windows brauche.
Ein Ausweg sind die Indys. Ich versuche gerade nach 10 Jahren wieder in das Thema zu kommen. Leider scheitere ich daran, dass es mir mit den Indys irgendwie nicht gelingen will, AnsiStrings (für Header und Daten) "verlustfrei" zu versenden.
Natürlich habe ich die Suche benutzt und habe diverse Dinge gefunden. Leider klappt aber folgender Code bei mir nicht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| Procedure TMainForm.Button1Click(Sender: TObject); Var Command : TCmdSeq; Begin Command:= TCmdSeq.Create($4711); Try Memo1.Lines.Append(Dump(Command.Frames)); Client.Socket.WriteLn(Command.Frames, IdGlobal.IndyTextEncoding_8Bit); Finally Command.Free; End; End;
Procedure TMainForm.ServerExecute(AContext: TIdContext); Var BinMessage : AnsiString; Begin If AContext.Connection.Socket.Readable Then Begin BinMessage:= AContext.Connection.Socket.ReadLn( IdGlobal.IndyTextEncoding_8Bit); Memo1.Lines.Append( IntToStr(Length(BinMessage)) + ' Zeichen gelesen: ' + #13#10 + Dump(BinMessage)); End; End; |
TCmdSeq arbeitet intern natürlich mit AnsiString und liefert auch das richtige Ergebnis
vor dem versenden. Wenn ich das durchlaufen lasse, erhalte ich folgende Ausgabe:
Quelltext
1: 2: 3:
| 04 00 00 80 01 00 11 47 8 Zeichen gelesen: 04 00 00 3F 01 00 11 47 |
Wie schaffe ich es, dass die Indys meinen AnsiString auch als solches behandeln und nicht "kaputt" machen?
Gruß, Alex
Schwedenbitter - Do 08.12.16 12:33
Ich habe natürlich weiter getestet und dachte schon, ich hätte es geschafft. Leider aber wohl doch nicht. Mit folgendem Code sah es ganz gut aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| Var T:Word = 0;
Procedure TMainForm.Button1Click(Sender: TObject); Var Command : TCmdSeq; Begin Command:= TCmdSeq.Create($4711); Try Command.Token:= T; Inc(T); Memo1.Lines.Append( IntToStr(Length(Command.Frames)) + ' Zeichen geschrieben: ' + #13#10 + Dump(Command.Frames)); Client.Socket.DefStringEncoding:= IdGlobal.IndyTextEncoding_UTF7; Client.Socket.WriteLn(Command.Frames); Finally Command.Free; End; End;
Procedure TMainForm.ServerExecute(AContext: TIdContext); Var BinMessage : AnsiString; Begin If AContext.Connection.Socket.Readable Then Begin AContext.Connection.Socket.DefStringEncoding:= Client.Socket.DefStringEncoding; BinMessage:= AContext.Connection.Socket.ReadLn; Memo1.Lines.Append( IntToStr(Length(BinMessage)) + ' Zeichen gelesen: ' + #13#10 + Dump(BinMessage) + #13#10 + '-----------------------------'); End; End; |
Abfänglich sehen die Ausgaben vielversprechend aus. Aber ab einem Zeichen mit $0A ist das ganze aber nicht mehr brauchbar:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| 8 Zeichen geschrieben: 04 00 00 80 01 00 09 00 8 Zeichen gelesen: 04 00 00 80 01 00 09 00 ----------------------------- 8 Zeichen geschrieben: 04 00 00 80 01 00 0A 00 6 Zeichen gelesen: 04 00 00 80 01 00 ----------------------------- 8 Zeichen geschrieben: 04 00 00 80 01 00 0B 00 1 Zeichen gelesen: 00 ----------------------------- 8 Zeichen geschrieben: 04 00 00 80 01 00 0C 00 8 Zeichen gelesen: 04 00 00 80 01 00 0B 00 ----------------------------- 8 Zeichen geschrieben: 04 00 00 80 01 00 0D 00 8 Zeichen gelesen: 04 00 00 80 01 00 0C 00 usw... |
Offenbar gibt es keine Möglichkeit, Strings in binärer Form mit den Indys zu versenden.
Ich habe dann mein Glück damit versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| Procedure TMainForm.Button1Click(Sender: TObject); Var ... Buffer : TIdBytes; Begin ... Buffer:= RawToBytes(Command.Frames, Length(Command.Frames)); Client.Socket.Write(Buffer); ...; End; Procedure TMainForm.ServerExecute(AContext: TIdContext); Var Buffer : TIdBytes; ByteCount : Integer; ... Begin ... ByteCount:= ??? AContext.Connection.Socket.ReadBytes(Buffer, ByteCount); BytesToRaw(Buffer, BinMessage, ByteCount); ... End; |
Allerdings weiß ich nicht, wie ich an die genau Anzahl der übertragenen Bytes gelange. Kann mir dabei jemand helfen?
Gruß, Alex