Proper use of IdUDPClient.ReceiveBuffer

4k views Asked by At

Thank you for your help.

I am converting an older version of Delphi to XE5 and I am getting stuck with the Indy compnent. Need to use IdUDPClient.ReceiveBuffer

Here is my code:

while not Terminated do
begin
  try
    lenUDP:= IdUDPClient.ReceiveBuffer(myBuf, buffLength, -1 );
    if lenUDP<> 0 then
      Synchronize(ReceivedLine);
  except
    Terminate;
  end;
end;

where, myBuf = packed array [0 .. buffLength -1] of char;

All help is greatly appreciated.

Thank you,

Mike

1

There are 1 answers

4
Remy Lebeau On

As I told you in comments to your previous question:

You have to use a TIdBytes for that as well. Use SetLength() to pre-allocate it to the desired size, then call ReceiveBuffer() with it, and then you can copy out data from it as needed, either directly or with BytesToRaw().

For example:

private
  myBuf: TIdBytes;
...

while not Terminated do
begin
  try
    SetLength(myBuf, buffLength);
    lenUDP := IdUDPClient.ReceiveBuffer(myBuf, -1);
    if lenUDP > 0 then
    begin
      SetLength(myBuf, lenUDP);
      Synchronize(ReceivedLine);
    end;
  except
    Terminate;
  end;
end;

Since your original buffer was an array of Char, and your processing function is named ReceivedLine(), I am assuming your data is textual in nature. If that is true, you can use BytesToString() or (T|I)IdTextEncoding.GetString() to convert a TIdBytes to a String, if that is what ReceivedLine() uses myBuf for, eg:

S := BytesToString(myBuf{, en8bit});

S := BytesToString(myBuf, 0, lenUDP{, en8bit});

S := IndyTextEncoding_8bit.GetString(myBuf);

S := IndyTextEncoding_8bit.GetString(myBuf, 0, lenUDP);

You can use any charset encoding that Indy supports, either via the various en...(), Indy...Encoding(), or IndyTextEncoding...() functions in the IdGlobal unit, or the CharsetToEncoding() function in the IdGlobalProtocols unit.

UPDATE: since your buffer is part of a record with a union in it, you will have to use a local TIdBytes variable instead:

type
  myRecord = record
    ...
    myBuf: array[0..buffLength-1] of Byte;
    ...
  end;

...

private
  myRec: myRecord;

...

var
  udpBuf: TIdBytes;
...
SetLength(udpBuf, buffLength);
while not Terminated do
begin
  try
    lenUDP := IdUDPClient.ReceiveBuffer(udpBuf, -1);
    if lenUDP > 0 then
    begin
      BytesToRaw(udpBuf, myRec.myBuf[0], lenUDP);
      Synchronize(ReceivedLine);
    end;
  except
    Terminate;
  end;
end;