Hi Alex,
Zitat von
AJ_Oldendorf:
Mit SendBuffer haben wir es auch schon probiert und hatten das gleiche Problem mit der Übertragung.
Wäre super, wenn du dir das Beispiel mal anguckst und mir Bescheid gibst.
So, ich habe mir das gerade mal angesehen. Meine Vermutung bezüglich des Encodings stimmt. Allein schon die Tatsache, daß der Compiler Warnungen bezüglich der String-Umwandlung schmeißt, sollte dem Programmierer immer zu denken geben.
Wenn Du in Deinem D2009 Beispiel folgendes änderst, geht es sofort - aber bitte trotzdem unten weiterlesen:
Delphi-Quellcode:
// Senden:
procedure TForm1.Timer1Timer(Sender: TObject);
var
outMsg: String[2];
begin
Inc(Counter);
outMsg[0] := AnsiChar(2);
outMsg[1] := AnsiChar(Hi(Counter));
outMsg[2] := AnsiChar(Lo(Counter));
// IdUDPClient1.Send(outMsg, Indy8BitEncoding);
IdUDPClient1.Send(outMsg, TEncoding.Unicode); // Delphi Encoding nutzen!
Label3.Caption := 'Sending: ' + IntToStr(Counter);
end;
...
// Empfangen:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TBytes; ABinding: TIdSocketHandle);
var
InData : AnsiString;
tmpword: Word;
begin
InData := BytesToString(AData, TEncoding.Unicode); // Delphi Encoding nutzen!
if (InData = '') or (Length(Indata) < 2) then
begin
Memo1.lines.Add('Invalid value');
end
else begin
// Read Word from ByteArray
tmpword := (Ord(InData[1]) shl 8) or
Ord(InData[2]);
Memo1.Lines.Add(IntToStr(tmpword));
end;
end;
Aber wie gesagt, das so zu nutzen wäre sehr unschön. IdUDPClient1.Send hat als 1. Übergabeparameter einen String. Was glaubst Du also, macht Delphi, wenn Du dort einen
Ansi oder ShortString übergibst? Richtig, es konvertiert diesen zu einem UnicodeString.
Der richtige Weg, diese Binärdaten zu übertragen wäre z.B.:
Delphi-Quellcode:
// Senden:
procedure TForm1.Timer1Timer(Sender: TObject);
var
outData: TBytes;
begin
Inc(Counter);
SetLength(outData, 2);
outData[0] := Hi(Counter);
outData[1] := Lo(Counter);
IdUDPClient1.SendBuffer(outData);
Label3.Caption := 'Sending: ' + IntToStr(Counter);
end;
...
// Empfangen:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TBytes; ABinding: TIdSocketHandle);
var
tmpword: Word;
begin
if Length(AData) < 2 then
begin
Memo1.lines.Add('Invalid value');
// Raise EProgrammerNotFound.Create('nicht da');
end
else begin
// Read Word from ByteArray
tmpword := (Ord(AData[0]) shl 8) or
Ord(AData[1]);
Memo1.Lines.Add(IntToStr(tmpword));
end;
end;
Und da gibt es dann natürlich auch keine Warnung mehr wegen irgendwelcher String-Conversions. Es werden direkt und unverändert Bytes übertragen.
Das Problem hat nichts, wirklich garnichts mit
Indy zu tun. Die Speicherung von Binärdaten in einem String und die daraus folgenden Probleme, kommen seit Delphi 2009 jetzt in vielen Sourcen ans Tageslicht. Ich empfehle dringend mal die Leitfäden bezüglich der D2009
Unicode-Umstellung von Embarcadero, da hier wirklich hilfreiche Infos drin stecken (einfach mal im EDN suchen).
Gruß Assertor