2016-07-05 16 views
5

Chỉ cần cố gắng Bonjour trong nhanh chóng 3Swift 3 cách giải quyết IP NetService?

Đây là mã của tôi, tôi có thể nhận được các đại biểu

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

Và đây là kết quả của tôi

netServiceDidResolveAddress tên dịch vụ Mac mini kiểu _myapp Webber ._tcp., cổng 5678, địa chỉ Tùy chọn ([< 1002162e c0a80205 00000000 00000000>, < 1c1e162e 00000000 fe800000 00000000 00bce7ad 24b4b7e8 08000000>])

c0a80205 là IP Tôi tìm kiếm => 192.168.2.5

Và địa chỉ là [Data], Apple nói

Các địa chỉ của dịch vụ. Đây là một NSArray của các cá thể NSData, mỗi trong số đó chứa một cấu trúc đơn sockaddr phù hợp để sử dụng với kết nối (2). Trong trường hợp không có địa chỉ nào được giải quyết cho dịch vụ hoặc dịch vụ chưa được giải quyết, NSArray trống sẽ được trả về .

Tôi vẫn nhầm lẫn lý do Dữ liệu không thể sử dụng .tyty? Như Apple nói "Đây là NSArray của các cá thể NSData" Nhưng tôi không thể sử dụng nó như NSData

Và cách giải quyết địa chỉ dưới dạng chuỗi IP có thể đọc được?

tôi cố gắng này trước đây, nhưng không nhận được kết quả như tôi trừ ...

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

Bất kỳ đề nghị sẽ được giúp đỡ, Cảm ơn

Trả lời

2

OK ... đây không phải là một câu trả lời thông minh, ít nhất tôi có thể nhận được IP có thể đọc được

Chỉ cần sử dụng func này để có được IP chuỗi

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

tôi có thể 'T làm cho nó làm việc với Data, nhưng sử dụng NSData, tôi sẽ sử dụng này:

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

Vì vậy, chúng tôi có 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)) 
      } 
     } 
    } 
} 

Tôi gặp kết quả như sau (lưu trữ ip trong mảng trước khi hiển thị) :

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

Mã lấy cảm hứng từ https://gist.github.com/agrippa1994/d8c66a2ded74fb2dd801 viết bằng Swift 2.3 và thích nghi cho Swift 3.0

7

Đây là cách tôi đã làm điều đó trong Swift 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) 
} 
Các vấn đề liên quan