Mr. Smit
Mr. Smit

Reputation: 2512

IdUDPClient , how to send a packet to server?

How to correctly send a packet to a UDP server? I'm trying but it's not working an I did not received anything from the server.

What I need is to send a packet: int64|int|int

And receive a packet back from the server: int|int|int64

How to do it correctly? Thanks.

type
  Tconnecting = record
    a: int64;
    b: integer;
    c: integer;
  end;
  Treply_connect = record
    a: integer;
    b: integer;
    c: int64;
  end;

var 
  udp: TIdUDPClient;
  send_data: TIdBytes;
  received_data: TIdBytes;
  i: integer;
  packet: Tconnecting;
  reply_packet: Treply_connect;

begin
  packet.a := 41727101980;
  packet.b := 0;
  packet.c := RandomRange(1, 9999999);
  SetLength(send_data, sizeof(packet));
  Move(packet, send_data[0], sizeof(packet));
  udp := TIdUDPClient.Create(nil);
  try
    udp.Host := 'server.com';
    udp.Port := 1234;
    udp.SendBuffer(send_data);
    SetLength(received_data, 0);
    i := udp.ReceiveBuffer(received_data, 5000);
    Memo1.Lines.Add('Data reiceived! Len:'+IntToStr(Length(received_data))+',data:|'+BytesToString(received_data, 0)+'|');
  finally
    FreeAndNil(udp);
  end;

Upvotes: 1

Views: 7726

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595320

You are not using ReceiveBuffer() correctly. You are setting the size of the output buffer to 0 bytes, so ReceiveBuffer() will not have any memory to read the received data into. You need to pre-allocate the output buffer to the max size you are expecting. The return value of ReceiveBuffer() will tell you how many bytes were actually read into the buffer.

In other words, change this:

SetLength(received_data, 0);

To this:

SetLength(received_data, SizeOf(Treply_connect));

And change this:

Memo1.Lines.Add('Data reiceived! Len:'+IntToStr(Length(received_data))+', data:|'+BytesToString(received_data, 0)+'|');

To this:

Memo1.Lines.Add('Data received! Len:'+IntToStr(i)+', data:|'+BytesToString(received_data, 0, i)+'|');

On a separate note, Indy has a RawToBytes() function you can use to copy your packet into a TIdBytes:

send_data := RawToBytes(packet, SizeOf(packet));

And a BytesToRaw() function for when you want to extract the received packet:

BytesToRaw(received_data, reply_packet, SizeOf(reply_packet));

Upvotes: 5

Related Questions