|
Registriert seit: 21. Mär 2012 Ort: Hannover 932 Beiträge Delphi 10.4 Sydney |
#7
Status: Tethering
- die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - Permission Internet muss auf "true" gesetzt sein - die iOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter iOS 14.x nicht gefunden werden (<iOS 14 funktioniert). Ursache: DoOnReceiveData wird unter iOS 14.x nie errreicht (gleiches gilt für MacOS 11.x) - Es muss via ![]() damit iOS 14.x funktioniert; im Projekt ist das Entitlement aber nicht zu setzen, dies passiert über das Provision Profile automatisch (außer man erzeugt die Entitlement-Datei manuell);
Delphi-Quellcode:
- die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter MacOS 11.x nicht gefunden werden (<MacOS 11.x funktioniert).
<key>com.apple.developer.networking.multicast</key>
<true/> Ursache: DoOnReceiveData wird unter MacOS 11.x nie errreicht (gleiches gilt für iOS 14.x) Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml oder via Projekt-Optionen):
Delphi-Quellcode:
Das Ticket für das iOS 14.x und MacOS 11.x-Problem ist unter
<key>com.apple.security.network.client</key>
<true/> <key>com.apple.security.network.server</key> <true/> ![]() Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen. Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen. Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.
Delphi-Quellcode:
Tipp 2: für iOS müssen eventuell alle Exception gefangen werden, weil ansonsten das nicht erfolgreiche binden eines Sockets zum Abbruch führen kann
CommandApp.Manager := CommandManager;
CommandManager.Enabled := True; Socket-Fehler # 48Adresse wird bereits verwendet: $0000000100BCFDD0 _ZN7Idstack8TIdStack16RaiseSocketErrorEi + 316 $0000000100BD0B74 _ZN7Idstack8TIdStack20RaiseLastSocketErrorEv + 72 $0000000100BD0A18 _ZN7Idstack8TIdStack19CheckForSocketErrorEi + 44 $0000000100BCBD00 _ZN15Idstackvclposix16TIdStackVCLPosix4BindEiN6Sys tem13UnicodeStringEtN8Idglobal12TIdIPVersionE + 344 $0000000100BD99E8 _ZN14Idsockethandle15TIdSocketHandle4BindEv + 316 $0000000100BF84F8 _ZN17Idcustomtcpserver18TIdCustomTCPServer14StartL isteningEv + 188
Delphi-Quellcode:
Tipp 3: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:
Application.OnException:=TgoExceptionReporter.ExceptionHandler;
TMessageManager.DefaultManager.SubscribeToMessage(TgoExceptionReportMessage, HandleExceptionReport);
Delphi-Quellcode:
Dies passiert an zwei Stellen:
uses IdStack, IdGlobal, System.Classes;
class var prefNetworkList:TStringList; class function getIPv4Address():String; function checkForPrefNetwork(value:String):boolean; var i:integer; begin Result:=false; for i:=0 to prefNetworkList.Count-1 do begin if (pos(prefNetworkList[i],value)=1) then begin Result:=true; exit; end; end; end; var AAddresses: TIdStackLocalAddressList; LAddr: TIdStackLocalAddress; I: Integer; IP: String; begin AAddresses:=TIdStackLocalAddressList.Create(); Result:=''; if (prefNetworkList=nil) then begin prefNetworkList:=TStringList.Create(); prefNetworkList.Add('192.168.'); end; try GStack.GetLocalAddressList(AAddresses); for I := 0 to AAddresses.Count-1 do begin LAddr:=AAddresses[I]; IP:=LAddr.IPAddress; if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetworkList.Count>0) and (checkForPrefNetwork(IP)) and (not checkForPrefNetwork(result))))) then begin case LAddr.IPVersion of Id_IPv4: begin log.d('Found IP-address*: '+IP); Result:=IP; end; Id_IPv6: begin log.d('Found IP-address: '+IP); end; end; end else log.d('Found IP-address: '+IP); end; finally AAddresses.Free; end; end; System.Tether.Manager.pas
Delphi-Quellcode:
System.Tether.NetworkAdapter.pas
constructor TTetheringAdapter.Create;
var ip:String; begin inherited; FRemoteManagers := TTetheringManagerInfoList.Create; ip:=getIPv4Address(); if (ip>'') then FAdapterConnectionString := ip else FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN; end;
Delphi-Quellcode:
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
... if not LListening then raise ETetheringException.Create(SManagerNetworkCreation); var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget else LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget; System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
Tipp 4: Tethering mit iOS bei aktivierten Mobilen Daten:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>); ... LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers, FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]); end else begin if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then begin var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]); end; Damit bei aktivierten Mobilen Daten unter iOS das Tethering funktioniert, muss die Funktion BroadcastData in System.Tether.Comm gefixt werden. Dies ist auch als Issue bei EMBT eingestellt ( ![]()
Delphi-Quellcode:
procedure TTetheringNetworkServerCommUDP.BroadcastData(const AData: TBytes; const AHost: string; InitialPort, FinalPort: Integer); var I, J: Integer; LHost: string; LData: TBytes; allWithException:boolean; toRaise:Exception; begin if TTetheringAdapter.IsLoggingItem(TTetheringAdapter.TTetheringLogItem.Comm) then TLogAdapter.Log('** UDP ** BroadcastData to "' + AHost + '": "' + TEncoding.UTF8.GetString(AData) + '"'); if AHost = '' then begin if FIPVersion = TCommIPVersion.IP_IPv4 then LHost := '255.255.255.255' else LHost := '0:0:0:0:0:0:255.255.255.255'; allWithException:=true; toRaise:=nil; for J := 0 to FUDPServer.Bindings.Count - 1 do begin try LData := TEncoding.UTF8.GetBytes(StringReplace( TEncoding.UTF8.GetString(AData), '|' + TetheringMULTIHOMED + '$', '|' + FUDPServer.Bindings.Sockets[J].IP + '$', [])); for I := InitialPort to FinalPort do FUDPServer.Bindings.Sockets[J].Broadcast(LData, I, LHost); allWithException:=false; except on E: Exception do begin if (toRaise=nil) then toRaise:=e; end; end; end; if (allWithException and (toRaise<>nil)) then raise(toRaise); end else for I := InitialPort to FinalPort do FUDPServer.SendBuffer(AHost, I, AData); end; Geändert von philipp.hofmann ( 9. Jun 2021 um 18:48 Uhr) |
![]() |
philipp.hofmann |
Öffentliches Profil ansehen |
Mehr Beiträge von philipp.hofmann finden |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |