简体   繁体   English

Indy UDP读取Adata的内容

[英]Indy UDP Read Contents of Adata

I am using Indy UDP Server to read a string of data. 我正在使用Indy UDP Server来读取一串数据。 However, I do not really know how to work with the Adata parameter. 但是,我真的不知道如何使用Adata参数。 I can get around it by converting it to binary by using the ByteToBin function below and then convert it to hex by using BintoHex1 . 我可以通过使用下面的ByteToBin函数将其转换为二进制来绕过它,然后使用BintoHex1将其转换为十六进制。 But I really feel this is really stupid and it works really slow. 但我真的觉得这真的很愚蠢而且效果很慢。 Does anyone know how I can directly get the results without those two conversions? 有没有人知道如何在没有这两次转换的情况下直接获得结果?

Thanks!! 谢谢!!

Here are the codes: 以下是代码:

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;

Your code is unnecessarily complex. 您的代码不必要地复杂。 Indy has many functions in its IdGlobal unit for working with TIdBytes data. Indy在其IdGlobal单元中具有许多功能,用于处理TIdBytes数据。 For example, you can simplify your example to the following: 例如,您可以将示例简化为以下内容:

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;

To convert AData to a string of hex characters, use the BinToHex function in the Classes unit. 要将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;

You can also get the data as AnsiChars directly to a string by using SetString function like this: 您还可以使用SetString函数将数据作为AnsiChars直接获取到字符串,如下所示:

var MyString: AnsiString;

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

However if you need HEX values, @Tom gave you the answer you need. 但是,如果您需要HEX值,@ Tom会为您提供所需的答案。

There are several functions to get Hex values already implemented in the Delphi itself, one is BinToHex mentioned in Tom's answer, then there's IntToHex where you can convert Integer or Byte values to Hex string, such as 有几个函数可以在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;

Depends what you actually need as result... 取决于你实际需要的结果......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM