Hi
DP-ler,
jetzt will ich Euch auf einen bösen Fehler in
procedure TIdTCPConnection.WriteRFCStrings hinweisen.
RFC Strings werden in vielen Text-basierten
TCP-Protokollen genutzt. Dabei wird dem Empfänger nicht gesagt, wie viele Bytes zu erwarten sind, jedoch stillschweigend vereinbart, daß die Übertragung der Daten durch ein
<CRLF>.<CRLF> beendet wird.
Damit es nicht zu Mißverständnissen kommt, wenn eine Zeile übertragen wird, die lediglich einen Punkt
. beinhaltet, werden, lt. Protokoll alle Zeilen, welche
mit einem starten durch einen vorangestellten Punkt erweitert.
Die
Indy-WriteRFCStrings Prozedur versucht dieses wie folgend zu lösen:
Delphi-Quellcode:
procedure TIdTCPConnection.WriteRFCStrings(AStrings: TStrings);
var
i: Integer;
begin
for i := 0 to AStrings.Count - 1 do
begin
// --- FEHLER !!!
if AStrings[i] = '.' then
begin
WriteLn('..');
end else
begin
WriteLn(AStrings[i]);
end;
end;
WriteLn('.');
end;
Da liegt der Fehler einfach zu sehen. Das
RFC gibt vor, daß alle Zeilen die mit einem Punkt starten einen weiteren vorangestellt bekommen, die
Indy-Methode erweitert allerdings nur Zeilen, welche ausschließlich einen Punkt haben
Daß dieses wirklich ein Fehler ist, kann man an der Capture-Methode erkennen, dort werden nämlich alle Zeilen, welche mit zwei Punkten starten um einen gekürzt
Code:
procedure TIdTCPConnection.PerformCapture(ADest: TObject; out VLineCount: Integer;
const ADelim: string; const AIsRFCMessage: Boolean);
const
[color=#ff0024]wDoublePoint = ord('.') shl 8 + ord('.');[/color]
type
PWord = ^Word;
var
s: string;
begin
VLineCount := 0;
BeginWork(wmRead); try
repeat
s := ReadLn;
if s = ADelim then
begin
Exit;
end;
// For
RFC 822 retrieves
// No length check necessary, if only one byte it will be byte x + #0.
[color=#ff0000]if AIsRFCMessage and (PWord(PChar(S))^ = wDoublePoint) then
begin
Delete(s, 1, 1);[/color]
end;
// Write to output
Inc(VLineCount);
if ADest is TStrings then
begin
TStrings(ADest).Add(s);
end else if ADest is TStream then
begin
TIdStream(ADest).WriteLn(s);
end else if ADest <> nil then
begin
raise EIdObjectTypeNotSupported.Create(RSObjectTypeNotSupported);
end;
until False;
finally EndWork(wmRead); end;
end;
Wie dem auch sei, da ihr ja die Source zu
Indy habt, könnt Ihr die Methode
WriteRFCStringsie folgend anpassen.
Code:
procedure TIdTCPConnection.WriteRFCStrings(AStrings: TStrings);
var
i: Integer;
begin
for i := 0 to AStrings.Count - 1 do
begin
[color=#f50000]if Copy(AStrings[i], 1, 1) = '.' then
begin
WriteLn('.' + AStrings[i]);[/color]
end else
begin
WriteLn(AStrings[i]);
end;
end;
WriteLn('.');
end;
Weiterhin viel Spass mit den kleinen Indianern
...
...
[edit=Chakotay1308]Titel angepasst. Mfg, Chakotay1308[/edit]