Перейти к содержанию
Fire Monkey от А до Я
  • 0

IdUDPServer1UDPRead на Андроид


OnePeople

Вопрос

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
 
Ругается на константы. Как заставить работать???
Добавлял для AData в uses idGlobal;
Но всё равно с AData ничего не сделать, на все его параметры среда ругается(
 
Вообще у меня Client нормально всё отрабатывает, а на компе сервер отвечает, может как то клиентом можно отловить ответ сервера?
Изменено пользователем OnePeople
Ссылка на комментарий

Рекомендуемые сообщения

  • 0
В 14.03.2016 в 11:57, OnePeople сказал:

Парни может хотя бы кто скажет, procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle) должна работать на андроид?

Не только должна, но и отлично работает. Вот пример:

function TFormMain.CreateUDPServer : Boolean;
Var I : Integer;
begin
  Result:=False;
  IdUDPServer:=TIdUDPServer.Create;
  IdUDPServer.BroadcastEnabled:=True;
  IdUDPServer.OnUDPRead:=IdUDPServerUDPRead;
  for I := Low(UDPPortArray) to High(UDPPortArray) do
  begin
    IdUDPServer.Bindings.Clear;
    with IdUDPServer.Bindings.Add do
    begin
      IP:='0.0.0.0';
      Port:=UDPPortArray[I];
    end;
    try
      IdUDPServer.Active:=True;
    except
    end;
    if IdUDPServer.Active then
    begin
      FActiveUDPPort:=IdUDPServer.Bindings.Items[0].Port;
      IPMACLocalPair.Port:=IdUDPServer.Bindings.Items[0].Port;
      Result:=True;
      Exit;
    end;
  end;
  FActiveUDPPort:=-1;
end;

procedure TFormMain.IdUDPServerUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
Var S : String;
begin
  if (IPMACLocalPair.IP.Equals(ABinding.PeerIP)) And (IPMACLocalPair.Port=ABinding.PeerPort) then exit;
  DateTimeToString(S, 'hh:nn:ss.zzz', Now);
  S:=S+' '+BytesToString(AData , IndyUTF8Encoding);
  S:=S+' | from '+ABinding.PeerIP+':'+ABinding.PeerPort.ToString;
  Memo.Lines.Insert(0,S);
end;

На UDPPortArray не обращайте внимание, это если порт занят, то используется другой (UDPPortArray : array [0..2] of Integer = (55771, 55772, 55773);). 

IdUDPServer.BroadcastEnabled:=True; тоже не нужно, если не собираетесь широковещать.

Большинство функций работы с TIdBytes доступны в юните idGlobal, как например BytesToString(AData , IndyUTF8Encoding) в моем коде.

Ссылка на комментарий
  • 0

Мне нужно чтоб UDPServer и UDPClient работали одновременно на одном порту и IP в одном приложении.

Реализую технологию UDP Hole Punching для peer-to-peer соединения (Peer-to-Peer Communication Across Network Address Translators)

Код уже написан и оттестирован под Win32, все работает как надо, но на Android почему-то не хочет.

Если клиент и сервер на одном порту, то сервер ничего не получает, ReuseSocket= true


 

 uClient := TIdUDPClient.Create( nil );
    uClient.ReuseSocket := TIdReuseSocket.rsTrue;
    uClient.OnConnected := ClientConnected;

    uClient.Host := '192.168.0.100';
    uClient.Port := 5551;
    uClient.BoundIP := '';
    uClient.BoundPort := 5551;
    uClient.Active := true;
    uClient.Connect;

procedure TPeerToPeerClient.ClientConnected(Sender: TObject);
begin
    bConToMainServer := true;
    sPrivateMyIP := uClient.Binding.IP;
    iPrivateMyPort  := uClient.Binding.Port;
    StartServer();
end;

Код сервера

    uServer := TIdUDPServer.Create( nil );
    uServer.ReuseSocket := TIdReuseSocket.rsTrue;
    uServer.OnUDPRead := ServerRead;   

    uServer.Active := false;
    uServer.Bindings.Clear;
    uServer.Bindings.Add;
    uServer.Bindings.Items[0].IP := sPrivateMyIP;
    uServer.Bindings.Items[0].Port := iPrivateMyPort;
    uServer.DefaultPort := iPrivateMyPort;
    uServer.IPVersion := Id_IPv4;
    uServer.ReuseSocket := TIdReuseSocket.rsTrue;
    uServer.ThreadedEvent := false;
    uServer.BroadcastEnabled := false;
    uServer.Active := true;

procedure TPeerToPeerClient.ServerRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var sCommand,sCl,sMessageText:string;
    i:integer;
    sync: TMySync;
begin
    sCommand := '';
    try
      i := 0;
      while (AData <> 0) do
      begin
        sCommand := sCommand + chr(AData);
        i := i + 1;
      end;
    finally
        ShowMessage(sCommand);
    end;

end;

 

Ссылка на комментарий
  • 0
7 часов назад, AlexShaman сказал:

Мне нужно чтоб UDPServer и UDPClient работали одновременно на одном порту и IP в одном приложении.

Реализую технологию UDP Hole Punching для peer-to-peer соединения (Peer-to-Peer Communication Across Network Address Translators)

Код уже написан и оттестирован под Win32, все работает как надо, но на Android почему-то не хочет.

Если клиент и сервер на одном порту, то сервер ничего не получает, ReuseSocket= true

Приложите проект который можно запустить, попробую помочь. Кстати может стоит отказаться от UDP клиента совсем? UDP сервер умеет все тоже что и клиент, плюс умеет слушать порт. 

Ссылка на комментарий
  • 0
14 часов назад, AlexShaman сказал:

Как можно передать файл, с контролем целостности данных?

Для этого лучше использовать TCPServer и TCPClient, протокол TCP сделает это все гораздо лучше, чем велосипед на UDP.

Но если именно UDP, то алгоритм такой: нумеруете все отправляемые пакеты, вставляя в тело пакета его номер, что бы на стороне приемника контролировать все ли пакеты пришли и в правильной ли последовательности (udp пакеты могут прийти не в той последовательности в которой отправлены), в завершении передачи отправляете хэш файла (md5 к примеру) для контроля целостности всего файла. Естественно при не получении какого то пакета, нужно отправлять запрос на сервер о повторной отправке. Желательно еще и хэш каждого пакета к нему присобачивать. Так же нужно учесть обрезку и дробление пакетов из за разных размеров MTU на промежуточных устройствах сети.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...