我正在使用Indy UDP Server来读取一串数据。但是,我真的不知道如何使用Adata
参数。我可以通过使用下面的ByteToBin
函数将其转换为二进制文件来解决它,然后使用BintoHex1
将其转换为十六进制。但我真的觉得这真的很愚蠢而且效果很慢。有没有人知道如何在没有这两次转换的情况下直接获得结果?
谢谢!
以下是代码:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
Buf: TIdBytes;
buffer: string;
Data_received: string;
begin
if bytestostring(AData) <> 'Hello' then
begin
buffer := HextoString('00');
SetLength(Buf, Length(buffer));
CopyTIdString(buffer, Buf, 0);
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, Buf);
Data_received := BinToHex1(ByteToBin(AData[1]) + ByteToBin(AData[2]) +
ByteToBin(AData[3]) + ByteToBin(AData[4]) + ByteToBin(AData[5]) +
ByteToBin(AData[6]) + ByteToBin(AData[7]) + ByteToBin(AData[8]) +
ByteToBin(AData[9]) + ByteToBin(AData[10]) + ByteToBin(AData[11]) +
ByteToBin(AData[12]));
end;
memo1.Lines.Add(Data_received);
Memo1.GoToTextEnd;
end;
function TForm1.ByteToBin(aByte: byte): String;
Const
c10: Array [Boolean] of Char = ('0', '1');
Var
eLoop1: byte;
Begin
SetLength(Result, 8);
For eLoop1 := 7 downto 0 do
Result[8 - eLoop1] := c10[(aByte and (1 shl eLoop1)) <> 0];
End;
function TForm1.BinToHex1(BinStr: string): string;
const
BinArray: array [0 .. 15, 0 .. 1] of string = (('0000', '0'), ('0001', '1'),
('0010', '2'), ('0011', '3'), ('0100', '4'), ('0101', '5'), ('0110', '6'),
('0111', '7'), ('1000', '8'), ('1001', '9'), ('1010', 'A'), ('1011', 'B'),
('1100', 'C'), ('1101', 'D'), ('1110', 'E'), ('1111', 'F'));
var
Error: Boolean;
j: Integer;
BinPart: string;
begin
Result := '';
Error := False;
for j := 1 to Length(BinStr) do
if not(BinStr[j] in ['0', '1']) then
begin
Error := True;
ShowMessage('This is not binary number');
Break;
end;
if not Error then
begin
case Length(BinStr) mod 4 of
1:
BinStr := '000' + BinStr;
2:
BinStr := '00' + BinStr;
3:
BinStr := '0' + BinStr;
end;
while Length(BinStr) > 0 do
begin
BinPart := Copy(BinStr, Length(BinStr) - 3, 4);
Delete(BinStr, Length(BinStr) - 3, 4);
for j := 1 to 16 do
if BinPart = BinArray[j - 1, 0] then
Result := BinArray[j - 1, 1] + Result;
end;
end;
end;
答案 0 :(得分:4)
您的代码不必要地复杂。 Indy在其IdGlobal
单元中具有许多用于处理TIdBytes
数据的功能。例如,您可以将示例简化为以下内容:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
if BytesToString(AData) <> 'Hello' then begin
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, ToBytes(Byte(0)));
end;
memo1.Lines.Add(ToHex(AData));
Memo1.GoToTextEnd;
end;
答案 1 :(得分:2)
要将Data转换为十六进制字符的字符串,请使用Classes单元中的BinToHex函数。
var
MyHexString: string;
...
begin
SetLength(MyHexString, 2 * Length(AData)); // 2 * because one byte is represented by two characters
BinToHex(AData, @MyHexString[1], Length(AData));
...
end;
答案 2 :(得分:2)
您也可以使用SetString函数将数据作为AnsiChars直接获取到字符串:
var MyString: AnsiString;
SetString(MyString, PAnsiChar(@AData[0]), Length(AData));
但是如果您需要十六进制值,@ Tom会为您提供所需的答案。
有几个函数可以在Delphi中实现Hex值,一个是Tom的答案中提到的BinToHex,然后是IntToHex,你可以将Integer或Byte值转换为Hex字符串,例如
// for int:
MyString:=IntToHex(integer, 2);
// or for byte:
MyString:=IntToHex(byte, 2);
// or for array of byte:
var MyArray: array of byte;
for i := 0 to Length(MyArray)-1 do
MyString:=MyString + ' ' + IntToHex(MyArray[i], 2);
// this adds all contents of MyArray to the string as Hex values, with space between each of them;
取决于您实际需要的结果......