【问题标题】:Indy UDP Read Contents of AdataIndy UDP 读取 Adata 的内容
【发布时间】:2014-11-28 05:52:20
【问题描述】:

我正在使用 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;

【问题讨论】:

  • 另外,请问您使用的是哪个版本的 Indy?据我记得,我的 Indy 使用 AData: Array of Byte 来存储 AData 字节,而不是 TIdBytes...我记得有一位 Indy 开发团队成员在我询问有关 AData 的问题时回答了这个问题...
  • @JustMarc: Indy 不再使用array of byte 作为AData 参数。那是bug that Embarcadero introduced in XE3,并在以后的版本中得到修复。
  • 那就是我的越野车 XE3,哈哈。我知道这是关于 Emba 的事情,因为我记得你解释过 Indy 团队不对此负责的话题。不记得是数组弄错了..

标签: delphi udp indy


【解决方案1】:

您的代码过于复杂。 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;

【讨论】:

  • 这正是我要找的!我学到了很多东西。感谢您和所有其他回复!
【解决方案2】:

要将 AData 转换为十六进制字符串,请使用 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;

【讨论】:

  • Indy 有自己的ToHex() 重载函数,其中一个以TIdBytes 作为输入。
【解决方案3】:

您还可以使用这样的 SetString 函数将数据作为 AnsiChars 直接获取到字符串:

var MyString: AnsiString;

SetString(MyString, PAnsiChar(@AData[0]), Length(AData));

但是,如果您需要 HEX 值,@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;

取决于你实际需要的结果......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多