Search code examples
delphiudpdelphi-7indyindy-9

Delphi - Why udp data packet is different?


I want understand why the data packet received in the Wireshark program is different of the sent by my delphi application. Can anyone help me?

Here is my code:

if Pos('\x',comandoRede.Comando) > 0 then
begin

  bufferS := Explode('\x',comandoRede.Comando);

  SetLength(buffer,Length(bufferS)-1);

  for J := 0 to Length(Buffer) -1 do
  begin

    buffer[J] := StrToInt('$'+bufferS[J+1]);

  end;

    TIdUDPServer(item).SendBuffer(equipamentoRede.IP,
      StrToInt(equipamentoRede.Port),buffer,Length(buffer));

end

Here the content of the buffer array:

Buffer

Here the log of the network sniffer Wireshark

Wireshark

I've tried with the TIDUDPClient as well, but the problem is the same.

Thanks for all help.


Solution

  • In Indy 9, SendBuffer() is declared as follows:

    procedure SendBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
    

    Note that the ABuffer is an untyped var. That means you can pass anything to it, and it receives the memory address of whatever variable you pass in.

    Your buffer is declared as a dynamic array (presumably, due to your use of SetLength()). A dynamic array is internally implemented as a pointer to a memory block that resides elsewhere in memory. When you pass a dynamic array variable to an untyped var parameter, the parameter receives the memory address of the variable itself, not the memory address of the array data that the variable points at. That is why you are seeing "garbage" being sent on the socket - you are actually sending the bytes of the data pointer itself! Your code happens to not crash, because your buffer length is 4 and pointers in Delphi 7 are 4 bytes in size.

    In order for the var parameter to receive the memory address of the actual array data, you must either:

    1. index into the first element of the array:

      TIdUDPServer(item).SendBuffer(..., buffer[0], Length(buffer));
      
    2. type-cast the array variable to the appropriate pointer type (in this case, presumably buffer is an array of Byte, so use PByte) and then dereference the pointer:

      TIdUDPServer(item).SendBuffer(..., PByte(buffer)^, Length(buffer));