2016-07-05 3 views
5

Nur Bonjour versuchen, in schnellen 3Swift 3 wie NetService IP aufzulösen?

Hier ist mein Code, ich die Delegaten

func netServiceDidResolveAddress(_ sender: NetService) { 
print("netServiceDidResolveAddress service name \(sender.name) of type \(sender.type)," + 
       "port \(sender.port), addresses \(sender.addresses)") 
} 

Und hier empfangen kann mein Ergebnis ist

netServiceDidResolveAddress Servicenamen Webbers Mac mini vom Typ _myapp ._tcp., Port 5678, Adressen Optional ([< 1002162e c0a80205 00000000 00000000>, < 1c1e162e 00000000 fe800000 00000000 00bce7ad 24b4b7e8 08000000>])

c0a80205 ist die IP-I für => 192.168.2.5

suchen und die Adresse [Daten], sagt Apple-

Die Adressen des Dienstes. Dies ist ein NSArray von NSData-Instanzen, , von denen jede eine einzelne Struktur sockaddr enthält, die zur Verwendung mit connect (2) geeignet ist. Wenn für den Dienst keine Adressen aufgelöst wurden oder der Dienst noch nicht aufgelöst wurde, wird ein leeres NSArray zurückgegeben.

Ich verwechsle immer noch, warum Daten .btyes nicht verwenden können? Wie Apple sagt "Dies ist ein NSArray von NSData Instanzen" Aber ich kann es nicht wie NSData

Und wie die Adresse als lesbare IP-String auflösen?

Ich versuche, dies vor, aber das Ergebnis als ich nicht außer bekommen ...

let thedata = NSData(bytes: sender.addresses, length: (sender.addresses?.count)!) 
var storage = sockaddr_storage() 
thedata.getBytes(&storage, length: sizeof(sockaddr_storage)) 

if Int32(storage.ss_family) == AF_INET { 
    let addr4 = withUnsafePointer(&storage) {UnsafePointer<sockaddr_in>($0).pointee } 
    print(inet_ntoa(addr4.sin_addr)); 
} 

Jeder Vorschlag Hilfe sein wird, Dank

Antwort

2

OK ... dies ist nicht eine intelligente Antwort, zumindest kann ich das lesbare IP

einfach diese func IP String

let bonjourDevices = [NetService]() 

let bonjourDevice = bonjourDevices[0] 

let host = self.getIPV4StringfromAddress(address:bonjourDevice.addresses!) 


func getIPV4StringfromAddress(address: [Data] , port : Int) -> String{ 

     let data = address.first! as NSData; 

     var ip1 = UInt8(0) 
     data.getBytes(&ip1, range: NSMakeRange(4, 1)) 

     var ip2 = UInt8(0) 
     data.getBytes(&ip2, range: NSMakeRange(5, 1)) 

     var ip3 = UInt8(0) 
     data.getBytes(&ip3, range: NSMakeRange(6, 1)) 

     var ip4 = UInt8(0) 
     data.getBytes(&ip4, range: NSMakeRange(7, 1)) 

     let ipStr = String(format: "%d.%d.%d.%d:%d",ip1,ip2,ip3,ip4,port); 

     return ipStr; 
    } 
2

zu bekommen verwenden bekommen kann ich ‚T es mit Data funktioniert, aber mit NSData, würde ich diese verwenden:

extension NSData { 
    func castToCPointer<T>() -> T { 
     let mem = UnsafeMutablePointer<T>.allocate(capacity: MemoryLayout<T.Type>.size) 
     self.getBytes(mem, length: MemoryLayout<T.Type>.size) 
     return mem.move() 
    } 
} 

So haben wir netServiceDidResolveAddress:

func netServiceDidResolveAddress(_ sender: NetService) { 
    if let addresses = sender.addresses, addresses.count > 0 { 
     for address in addresses { 
      let data = address as NSData 

      let inetAddress: sockaddr_in = data.castToCPointer() 
      if inetAddress.sin_family == __uint8_t(AF_INET) { 
       if let ip = String(cString: inet_ntoa(inetAddress.sin_addr), encoding: .ascii) { 
        // IPv4 
        print(ip) 
       } 
      } else if inetAddress.sin_family == __uint8_t(AF_INET6) { 
       let inetAddress6: sockaddr_in6 = data.castToCPointer() 
       let ipStringBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: Int(INET6_ADDRSTRLEN)) 
       var addr = inetAddress6.sin6_addr 

       if let ipString = inet_ntop(Int32(inetAddress6.sin6_family), &addr, ipStringBuffer, __uint32_t(INET6_ADDRSTRLEN)) { 
        if let ip = String(cString: ipString, encoding: .ascii) { 
         // IPv6 
         print(ip) 
        } 
       } 

       ipStringBuffer.deallocate(capacity: Int(INET6_ADDRSTRLEN)) 
      } 
     } 
    } 
} 

Ich habe folgendes Ergebnis (ips in Array vor der Anzeige zu speichern) :

["172.16.10.120", "172.16.8.251", "::", "::82c9:d9a5:2eed:1c87"] 

-Code von https://gist.github.com/agrippa1994/d8c66a2ded74fb2dd801 in Swift 2.3 und angepasst für Swift 3.0

geschrieben inspiriert
7

Hier ist, wie ich es in Swift 3 gemacht habe.

func netServiceDidResolveAddress(_ sender: NetService) { 
    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 
    guard let data = sender.addresses?.first else { return } 
    data.withUnsafeBytes { (pointer:UnsafePointer<sockaddr>) -> Void in 
     guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else { 
      return 
     } 
    } 
    let ipAddress = String(cString:hostname) 
    print(ipAddress) 
}