Indy UDP读取Adata的内容

时间:2014-11-27 09:29:50

标签: delphi udp indy

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

3 个答案:

答案 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;

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