IdUDPClient, как отправить пакет на сервер?

Как правильно отправить пакет на UDP-сервер? Я пытаюсь, но это не работает, я ничего не получил от сервера.

Мне нужно отправить пакет: int64|int|int

И получить ответный пакет от сервера: int|int|int64

Как это сделать правильно? Спасибо.

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;

person waza123    schedule 21.11.2012    source источник


Ответы (1)


Вы неправильно используете ReceiveBuffer(). Вы устанавливаете размер выходного буфера равным 0 байт, поэтому у ReceiveBuffer() не будет памяти для чтения полученных данных. Вам необходимо предварительно выделить выходной буфер до максимального размера, который вы ожидаете. Возвращаемое значение ReceiveBuffer() покажет вам, сколько байтов было действительно прочитано в буфер.

Другими словами, измените это:

SetLength(received_data, 0);

К этому:

SetLength(received_data, SizeOf(Treply_connect));

И измените это:

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

К этому:

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

Отдельно стоит отметить, что у Indy есть функция RawToBytes(), которую вы можете использовать для копирования вашего пакета в TIdBytes:

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

И функция BytesToRaw(), когда вы хотите извлечь полученный пакет:

BytesToRaw(received_data, reply_packet, SizeOf(reply_packet));
person Remy Lebeau    schedule 22.11.2012