2016-07-05 23 views
5

BenSwift 3 NetService IP nasıl çözümlenir? Sadece Burada hızlı 3</p> <p>Bonjour'u çalışırken

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

Ve burada tip _myapp ait

netServiceDidResolveAddress hizmet adı Webber'in Mac mini, benim sonucudur temsilci alabilir, benim kodudur ._tcp., port 5678, adresleri İsteğe bağlı (< 1c1e162e 00000000 fe800000 00000000 00bce7ad 24b4b7e8 08000000>]) 01 İsteğe bağlı (Adres: 1002162e c0a80205 00000000 00000000)

c0a80205 Apple hizmetinin

adreslerini diyor IP I => 192.168.2.5

arayan Ve adresi [Data] olmasıdır. Bu, her biri connect (2) ile kullanıma uygun tek bir struct sockaddr içeren bir NSData örneğidir, . hizmeti için hiçbir adres çözümlenmemiş veya hizmet henüz çözümlenmemişse, boş bir NSArray döndürülür.

Verilerin neden kullanamadıklarını hala karıştırıyorum. Apple'ın "Bu NSData örneklerinin bir NSArray'ı" olduğu gibi Ama bunu NSData

gibi kullanamıyorum Ve adresi okunabilir IP dizesi olarak nasıl çözebilirim?

Ben, tamam ... Bu akıllı çözüm değildir

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)); 
} 

Herhangi bir öneri yardım olacak, teşekkürler

cevap

2

... önce bu deneyin, ama haricinde I olarak sonuç alamadım en azından ben

Sadece IP dize

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

elimden almak için bu fonksiyonları kullanılabilmektedir okunabilir IP'yi alabilirsiniz 'T o Data ile çalışması, ancak NSData kullanarak, bunu kullanmaktan olacaktır:

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() 
    } 
} 

yüzden netServiceDidResolveAddress var:

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)) 
      } 
     } 
    } 
} 

I (gösterilmeden önce dizide ips saklanması) aşağıdaki sonucu yaşıyorum :

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

Kod

Swift 3.0 Swift 2.3 yazılmış https://gist.github.com/agrippa1994/d8c66a2ded74fb2dd801 esinlenerek uyarlanmış
7

İşte ben Swift 3'te bunu nasıl yaptım.

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) 
}