2016-07-05 9 views
5

बस तेजी से 3स्विफ्ट 3 NetService आईपी को कैसे हल करें?

यहाँ में Bonjour कोशिश कर मेरी कोड है, मैं

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

और यहाँ मेरी परिणाम है

netServiceDidResolveAddress सेवा का नाम वेबर की मैक के प्रकार _myapp मिनी प्रतिनिधि प्राप्त कर सकते हैं ._tcp।, पोर्ट 5678, वैकल्पिक वैकल्पिक ([< 1002162e c0a80205 00000000 00000000>, < 1c1e162e 00000000 fe800000 00000000 00bce7ad 24b4b7e8 08000000>])

c0a80205 आईपी मैं => 192.168.2.5

की तलाश में और पता है [डेटा], एप्पल का कहना है

सेवा के पते है। यह एनएसडीएटा उदाहरणों का एक एनएसएआरआरई है, जिनमें से प्रत्येक में एक ही संरचना सॉकड्रर है जो कनेक्ट (2) के साथ उपयोग के लिए उपयुक्त है। यदि सेवा के लिए कोई पता हल नहीं किया गया है या सेवा अभी तक हल नहीं हुई है, तो एक खाली NSArray लौटाया गया है।

मैं अभी भी उलझन में हूं कि डेटा क्यों उपयोग नहीं कर सकता .btyes? जैसा कि ऐप्पल कहता है "यह एनएसडीएटा उदाहरणों का एनएसएआरआरई है" लेकिन मैं इसका उपयोग एनएसडीटा

और पठनीय आईपी स्ट्रिंग के रूप में पते को कैसे हल करें?

मैं इस से पहले की कोशिश, लेकिन सिवाय मैं के रूप में परिणाम प्राप्त नहीं है ...

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

कोई भी सुझाव सहायता हो जाएगा, धन्यवाद

उत्तर

2

ठीक है ... यह एक चतुर जवाब नहीं है, कम से कम मैं पठनीय आईपी

बस आईपी स्ट्रिंग पाने के लिए

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

मैं इस समारोह का उपयोग प्राप्त कर सकते हैं 'टी यह Data के साथ काम करते हैं, लेकिन NSData का उपयोग कर, मैं इस का प्रयोग करेंगे:

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

तो हम 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)) 
      } 
     } 
    } 
} 

मैं निम्नलिखित परिणाम (प्रदर्शन से पहले सरणी में ips भंडारण) हो रहा है :

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

कोड https://gist.github.com/agrippa1994/d8c66a2ded74fb2dd801 स्विफ्ट 2.3 में लिखा से प्रेरित है और स्विफ्ट 3.0 के लिए

०१२३५१६४१०६ अनुकूलित
7

यहां मैंने स्विफ्ट 3 में यह कैसे किया है।

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