Delphi iOS的IPv6麻烦。 请确保您的应用程序与IPv6networking兼容
我不能将我的iOS应用发布到AppStore。
Delphi 10.1.2柏林,iOS64,Win 8.1。
我收到苹果的下一个信息:
感谢您的答复。
请确保您的应用程序与IPv6networking兼容。
testing您的应用程序以实现IPv6兼容性的最简单方法是在Mac上设置本地IPv6networking。 然后,您可以从iOS设备连接到networking,以testingIPv6兼容性。
请按照支持IPv6 DNS64 / NAT64networking提供的分步说明进行操作。
有关支持IPv6networking的更多信息,请查阅支持IPv6的networking。
这是连接代码。
if (FSocket<>nil) then begin if not FSocket.Connected then begin SetState(mwtrstDisConnected); FSocket.Free; FSocket:=nil; end else exit; end; FSocket:=TIdTCPClient.Create(nil); FSocket.Host:=FHost; FSocket.Port:=FPort; //CheckCode {$ifdef KBMMW_USING_INDY_9_OR_NEWER} FSocket.BoundPortMin:=FMinClientPort; FSocket.BoundPortMax:=FMaxClientPort; {$endif} {$IFDEF KBMMW_USING_INDY_10} FSocket.ReadTimeout:=RequestTimeout*1000; FSocket.ConnectTimeout:=ConnectTimeout*1000; {$ENDIF} {$IFDEF KBMMW_USING_INDY_8_00_23} FSocket.Connect; {$ELSE} {$IFDEF KBMMW_USING_INDY_9} FSocket.Connect(ConnectTimeout*1000); {$ELSE} FSocket.Connect; {$ENDIF} {$ENDIF} DoConnected(Info);
在我看来,我必须在// CheckCode地方插入下一个代码。
TIdStack.IncUsage; IdURI := TIdURI.Create('195.34.x.x'); try try ss := GStack.ResolveHost(IdURI.Host, TIdIPVersion.Id_IPv6); IdURI.IPVersion := TIdIPVersion.Id_IPv6; except IdURI.IPVersion := TIdIPVersion.Id_IPv4; // Just in case. end; //ShowMessage(ss); finally FreeAndNil(IdURI); TIdStack.DecUsage; end;
但是这个代码(GStack.ResolveHost)不适用于iOS。
如何解决?
尝试更像这样的东西,而不是:
FSocket := TIdTCPClient.Create(nil); FSocket.Host := FHost; FSocket.Port := FPort; {$IFDEF KBMMW_USING_INDY_9_OR_NEWER} FSocket.BoundPortMin := FMinClientPort; FSocket.BoundPortMax := FMaxClientPort; {$ENDIF} {$IFDEF KBMMW_USING_INDY_10} FSocket.ReadTimeout := RequestTimeout*1000; FSocket.ConnectTimeout := ConnectTimeout*1000; // check if connecting to an IPv4/IPv6 address directly... if GStack.IsIP(FHost) then // only checks for IPv4 right now begin FSocket.IPVersion := Id_IPv4; FSocket.Connect; end else if MakeCanonicalIPv6Address(FHost) <> '' then begin FSocket.IPVersion := Id_IPv6; FSocket.Connect; end else begin // connecting to a hostname, try IPv6 first, then fallback to IPv4... try FSocket.IPVersion := Id_IPv6; FSocket.Connect; except FSocket.IPVersion := Id_IPv4; FSocket.Connect; end; end; {$ELSE} // only IPv4 is supported... {$IFDEF KBMMW_USING_INDY_9} FSocket.Connect(ConnectTimeout*1000); {$ELSE} FSocket.Connect; {$ENDIF} {$ENDIF} DoConnected(Info);
或者:
var LIPAddress: TIdIPAddress; LLocalIPs: TIdStackLocalAddressList; TryIPv4, TryIPv6: Boolean; I: Integer; ... FSocket := TIdTCPClient.Create(nil); FSocket.Host := FHost; FSocket.Port := FPort; {$IFDEF KBMMW_USING_INDY_9_OR_NEWER} FSocket.BoundPortMin := FMinClientPort; FSocket.BoundPortMax := FMaxClientPort; {$ENDIF} {$IFDEF KBMMW_USING_INDY_10} FSocket.ReadTimeout := RequestTimeout*1000; FSocket.ConnectTimeout := ConnectTimeout*1000; LIPAddress := TIdIPAddress.MakeAddressObject(FHost); if LIPAddress <> nil then begin // connecting to an IPv4/IPv6 address... FSocket.IPVersion := LIPAddress.AddrType; LIPAddress.Free; FSocket.Connect; end else begin // connecting to a hostname... TryIPv4 := False; TryIPv6 := False; LLocalIPs := TIdStackLocalAddressList.Create; try GStack.GetLocalAddressList(LLocalIPs); for I := 0 to LLocalIPs.Count-1 do begin case LLocalIPs[I].IPVersion of Id_IPv4: TryIPv4 := True; Id_IPv6: TryIPv6 := True; end; end; finally List.Free; end; if TryIPv6 then begin try FSocket.IPVersion := Id_IPv6; FSocket.Connect; TryIPv4 := False; except if not TryIPv4 then raise; end; end; if TryIPv4 then begin FSocket.IPVersion := Id_IPv4; FSocket.Connect; end; if not (TryIPv4 or TryIPv6) then raise Exception.Create('Not connected to an IPv4 or IPv6 network'); end; {$ELSE} // only IPv4 is supported... {$IFDEF KBMMW_USING_INDY_9} FSocket.Connect(ConnectTimeout*1000); {$ELSE} FSocket.Connect; {$ENDIF} {$ENDIF} DoConnected(Info);
请注意,一旦Indy实现了以下function,这种情况将变得更加简单,但我认为这是一个解决办法:
支持循环DNS(支持连接到IPv4 / IPv6主机名)