indy10udpclientdelphi-10.3-riojedi

Indy 10 TIdUDPclient - detect wrong/no Answer


Using delphi 10.3 and JEDI VCL. I have a communication with a device, which responds to UDP data. Now I want to be able to check if I got an answer from the right device, or if if I even got any answer.

Currently I am using the following:

function TDIB.ReadData(ACommandCode: WORD; ASendLength : Cardinal; AReceiveLength : Cardinal; AAddress : Cardinal) : Integer;
var
  cmdHeader   : PDIBCommandHeader;
  UDPSend, UDPRecv    : TIdBytes;
  client              : TIdUDPClient;
begin
gRequestPending := TRUE;

// Reserviere Speicher
SetLength(UDPSend, SIzeOF(TDIBCommandHeader) + Cardinal(ASendLength));
SetLength(UDPRecv, SIzeOF(TDIBCommandHeader) + Cardinal(AReceiveLength));
cmdHeader := @UDPSend[0];
cmdHeader.Init(WORD(ACommandCode), AAddress, MAX(ASendLength, AReceiveLength));
client        := TIdUDPClient.Create();
try      
  client.Host   := ValToIPv4(gDIBAddress);
  client.Port   := TDIBPorts.mainPort;
  client.Active           := TRUE;


  client.sendBuffer       (UDPSend);
  client.ReceiveBuffer(UDPRecv,TDIB.C_CMDTimeout);
except
  on E: Exception do

  begin
    ShowMessage('Exception');
    client.Free;
  end;
end;

SetLength(lastUDPData, Length(UDPRecv));
move (UDPRecv[0],lastUDPData[0],Length(UDPRecv));

client.Free;
gRequestPending := FALSE;
end;

Which is fine when the client is responding, but I am not catching any misbehaviour, like when the host machine tries to reach the client and the client is not responding.

From the documentation of Indy10 I am missing something like TIdUDPClient.TimedOut or like that.

I want to be able to tell, if the client is not responding after Xms after I sent the UDP packet and I want to be able to check, if the sender address is the wanted client IP.


Solution

  • I want to be able to tell, if the client is not responding after Xms after I sent the UDP packet

    ReceiveBuffer() returns the number of bytes actually received. If no packet is received within the specified timeout, ReceiveBuffer() will return 0.

    I want to be able to check, if the sender address is the wanted client IP.

    Use one of the ReceiveBuffer() overloads that has a VPeerIP output parameter. That will give you the sender IP if a packet is received, or it will give you an empty string if no packet is received.

    Do be aware that UDP has a concept of a 0-byte datagram. ReceiveBuffer() will return 0 for that as well. In the case that 0 is returned, you can use this output string to differentiate between no packet received (VPeerIP = '') vs a 0-byte packet received (VPeerIP <> ''), if needed.