2016-06-06 5 views
0

IPv6 전용 환경에서 연결할 수 있어야하는 새로운 iOS 요구 사항을 처리하기 위해 소켓 코드를 업데이트하고 있습니다.호스트 이름에서 IPv6 주소 확인

우리는 현재 .NET 소켓과 TcpClient를 사용하고 있습니다.

IPv6와 IPv4가 모두 작동하는 솔루션을 설정하려고하지만 지금까지 아무 것도 일어나지 않았습니다.

내가 사용하는 경우 :

IPv6 환경에서
TcpClient client = new TcpClient(); 
client.BeginConnect("server.hostname.com", 8182, this._onConnect, client); 

, 내가 응답을 얻을; _onConnect 메서드가 실행되지 않습니다.

내가 사용하는 경우 :

TcpClient client = new TcpClient(AddressFamily.InterNetworkV6); 
client.BeginConnect("server.hostname.com", 8182,this._onConnect, client); 

내가 SocketException를 얻을 : 이해할 경우, 짜증나는

An address incompatible with the requested protocol was used (errorCode: 10047, socketErrorCode: AddressFamilyNotSupported, nativeErrorCode: 10047) 

. 내가 사용하는 경우 :

TcpClient client = new TcpClient(AddressFamily.InterNetworkV6); 
client.BeginConnect("xxxx:xxxx:xxxx::xxxx:xxxx", 8182,this._onConnect, client); 

을 그리고 나는 그러나, 연결할 수 있습니다

    지금
  • 이 의지 좋지 않아 대신 호스트 이름의 원시 IP 주소에 걸었습니다
  • IPv4 환경에서 더 이상 작동하지 않습니다.

그래서 호스트 이름에서 지원되는 IP를 가져 와서 다른 하나에 연결하려고 시도했습니다. 이 코드

:

IPHostEntry hostInfo = Dns.GetHostEntry("server.hostname.com"); 
foreach(IPAddress ip in hostInfo.AddressList) 
    Debug.Log("Ip: " + ip.ToString() + ": address family: " + ip.AddressFamily); 

그것은 단지 슈퍼 도움이되지는 IPv4 IP를, 인쇄 할 수 있습니다.

내가 뭘 잘못하고 있니? 문자열 호스트 이름에서 IPv6 IP를 가져 오는 방법은 무엇입니까? 아니면 이것을 해결할 더 좋은 방법이 있습니까?

나는 이것이 DNS 수준에서 자동 해결 될 것이라고 생각했지만, Unity에 포함 된 Mono 버전은 최신 버전이 아닌 것 같습니다.

감사

+0

그것의 닷넷 (I와 함께 제공되는'System.Net.Sockets.TcpClient' 클래스 Unity가 .Net 2.0에 있다고 생각하십시오.) : https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.80).aspx – divillysausages

답변

2

그것은 만들거나 실패 서버에 연결하는 호스트 이름을 통과, 모노처럼 보인다. 직접 IP를 사용하면 항상 작동합니다. Unity는 오랫동안 모노 소켓 물건을 업데이트하지 않았습니다. IP를 사용하는 데는 아무런 문제가 없습니다.

첫 번째 애플 마감 시간을 놓쳤습니다. 내 제안은 먼저 앱이 iOS에서 실행 중인지 확인한 다음 모든 것을 IPv6로 사용하는 것입니다. IPv6가 실패하거나 널 (NULL)을 리턴하면 IPv4를 사용하십시오.

매우 유용한 것은 아니지만 IPv4 IP 만 인쇄합니다.

내가 뭘 잘못하고 있니? 어떻게 문자열에서 IPv6 IP를 얻을 수 있습니까 호스트 이름? 아니면 이것을 해결할 더 좋은 방법이 있습니까?당신이 하지 필터를했기 때문에

그것은 IPv4의을 인쇄합니다. IP가 각 루프에서 IPv6인지 수동으로 확인해야합니다.

//IPv4 
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
{ 
} 

//IPv6 
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) 
{ 
} 

경우 IPv6를은 당신이에있는 네트워크가 하지 지원 IPv6를을 수행한다는 것을 의미 그렇다하더라도 그것을 필터링 위의 솔루션을 사용 후 찾을 수 없습니다. 내가 말할 때, 나는 당신의 ISP를 의미합니다. ISP가 IPv6을 제공하지 않은 경우 인 다른 공용 서버에 연결할 수 없습니다. ISP가 할당 한 을 사용하는 공용 서버에만 연결합니다.

여기까지 herehere을 방문하십시오. IPv4, 또는 둘 다 있으면 알려줍니다.

아래 코드는 제가 버전 4와 6을 포함하여 지역의 공공 IP를 검색하는 데 사용하는 일반 기능입니다

private string getIPAddress(string hostName, IPTYPE ipType, ADDRESSFAM Addfam) 
    { 
     //Return null if ADDRESSFAM is Ipv6 but Os does not support it 
     if (Addfam == ADDRESSFAM.IPv6 && !System.Net.Sockets.Socket.OSSupportsIPv6) 
     { 
      return null; 
     } 

     //////////////HANDLE LOCAL IP(IPv4 and IPv6)////////////// 
     if (ipType == IPTYPE.LOCAL_IP) 
     { 

      System.Net.IPHostEntry host; 
      string localIP = ""; 
      host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()); 
      foreach (System.Net.IPAddress ip in host.AddressList) 
      { 
       //IPv4 
       if (Addfam == ADDRESSFAM.IPv4) 
       { 
        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
        { 
         localIP = ip.ToString(); 
        } 
       } 

       //IPv6 
       else if (Addfam == ADDRESSFAM.IPv6) 
       { 
        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) 
        { 
         localIP = ip.ToString(); 
        } 
       } 
      } 
      return localIP; 

     } 

     //////////////HANDLE PUBLIC IP(IPv4 and IPv6)////////////// 
     if (ipType == IPTYPE.PUBLIC_IP) 
     { 
      //Return if hostName String is null 
      if (string.IsNullOrEmpty(hostName)) 
      { 
       return null; 
      } 

      System.Net.IPHostEntry host; 
      string localIP = ""; 
      host = System.Net.Dns.GetHostEntry(hostName); 
      foreach (System.Net.IPAddress ip in host.AddressList) 
      { 
       //IPv4 
       if (Addfam == ADDRESSFAM.IPv4) 
       { 
        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
        { 
         localIP = ip.ToString(); 
        } 
       } 

       //IPv6 
       else if (Addfam == ADDRESSFAM.IPv6) 
       { 
        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) 
        { 
         localIP = ip.ToString(); 
        } 
       } 

      } 
      return localIP; 
     } 
     return null; 
    } 


    enum IPTYPE 
    { 
     LOCAL_IP, PUBLIC_IP 
    } 

    enum ADDRESSFAM 
    { 
     IPv4, IPv6 
    } 

사용법 : 프로그래머의 코드 @

Debug.Log("Local IPv4: " + getIPAddress("", IPTYPE.LOCAL_IP, ADDRESSFAM.IPv4)); 
    Debug.Log("Local IPv6: " + getIPAddress("", IPTYPE.LOCAL_IP, ADDRESSFAM.IPv6)); 

    Debug.Log("Public IPv4: " + getIPAddress("google.com", IPTYPE.PUBLIC_IP, ADDRESSFAM.IPv4)); 
    Debug.Log("Public IPv6: " + getIPAddress("google.com", IPTYPE.PUBLIC_IP, ADDRESSFAM.IPv6)); 
+0

고맙습니다. 문제는 iOS 코드가 백엔드에서 다른 것 같습니다. 나는 그 질문에 답할 때 대답을 받아 들였지만, 짧게 말해 호스트 이름은 iOS에서 작동하지만 편집기와 안드로이드에서 예외가 발생합니다. 화합으로 버그를 열었습니다. – divillysausages

+0

또한'System.Net.Sockets.Socket.OSSupportsIPv6'는 Android에서 예외를 던집니다. 'SupportsIPv6'가 작동하는 것처럼 보이지만 쓸데없는 것으로 표시되었습니다. – divillysausages

+0

@divillysausages 예, 버그이며 hostname을 직접 사용하지 않았습니다. 하나의 Os에서는 작동하지만 다른 하나에서는 작동하지 않는 코드를 사용하지 않을 것입니다. 어쨌든 예외를 던지면 get IP 함수에서'System.Net.Sockets.Socket.SupportsIPv6'을 제거하십시오. 쿠도가 벌레를 여는거야. 버그도 http://blogs.unity3d.com/2016/05/10/unity-and-ipv6-support/에 게시하십시오. 유니티 (Unity)는 애플이 요구 사항을 만들었 기 때문에 네트워크 버그를 심각하게 받아 들일 것입니다. 유니티 (Unity)는 실수로 인해 아무도 앱이 거부되거나 버려지는 것을 막기 위해 노력하고 있습니다. – Programmer

2

는 IP 주소를 제공합니다 hostname하지만 2 가지를 명확히하고 싶었습니다.

1) 코드 :

TcpClient client = new TcpClient(AddressFamily.InterNetworkV6); 
client.BeginConnect("server.hostname.com", 8182,this._onConnect, client); 

는하지만 iOS에서, 작업을 수행합니다. 에디터와 안드로이드에서는 예외가 있습니다 (Unity 5.3.5f1 현재). 이것은 구현의 버그처럼 보이므로 버그 보고서를 보냈습니다. System.Net.Sockets.Socket.SupportsIPv6에도 불구하고

2) OSSupportsIPv6 안드로이드에 예외가 발생합니다, System.Net.Sockets.Socket.OSSupportsIPv6와 함께 갈 당신을 조언 쓸모과 단결로 표시되는

+0

더 깊이 파고 들자 ".Net 2.0"과 ".Net 2.0 Subset"호환성 수준에 문제가 있음이 밝혀졌습니다.전체가하지 않은 동안 부분 집합은 일했습니다. 서브 세트로 변경하면 이제 호스트 이름을 사용할 수 있으며'Socket.OSSupportsIPv6'는 더 이상 예외를 throw하지 않습니다 - 버그 보고서 : https://fogbugz.unity3d.com/default.asp?804510_c5ei44diq6ktnh1u – divillysausages