• 0
OnePeople

IdUDPServer1UDPRead на Андроид

Вопросы

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 ответов на этот вопрос

  • 0

ПКМ по TIdUDPListenerThread/TIdBytes/TIdSocketHandle любому другому неизвестному типу - Рефактор - Find Unit

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

ПКМ по TIdUDPListenerThread/TIdBytes/TIdSocketHandle любому другому неизвестному типу - Рефактор - Find Unit

 

Вот что говорит:

System.NullReferenceException: Object reference not set to an instance of an object

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

У меня сервер ничего не получает, может надо какие-то разрешения дать приложению?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 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

Уже разобрался, немного переделал. Сервер включен всегда, а клиент работает по схеме Connected-Send-Disconected

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
14 часов назад, AlexShaman сказал:

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

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

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