【问题标题】:How to get IP and PORT of a service published by AVAHI in iOS swift?如何在 iOS swift 中获取 AVAHI 发布的服务的 IP 和 PORT?
【发布时间】:2017-06-28 09:41:27
【问题描述】:

我正在使用 NSNetServiceBrowser,并且能够在“didFindService”中找到由 AVAHI 发布的服务列表,如下所示: 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B9ED382 -1 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B8E3916 -1 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B9ED380 -1

但无法找到同一服务的 IP 地址和端口号。我发现“netServiceDidResolveAddress”中的代码没有到达我的代码是:

class ServiceDiscovery : NSObject, NSNetServiceBrowserDelegate,NSNetServiceDelegate {

    var _browser:NSNetServiceBrowser!
    var _service: NSNetService!
    var services = [NSNetService]()
    override init() {
        _browser = NSNetServiceBrowser()
        super.init()
        _browser.delegate = self
        _browser.includesPeerToPeer = true
        _browser.searchForServicesOfType("_https._tcp.", inDomain: "local.")
        _browser.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

    }


    func netServiceBrowser(browser: NSNetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
        print(domainString)
    }

    func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didFindService aNetService: NSNetService, moreComing: Bool) {
       print("Service appeared: \(aNetService)")
        services.append(aNetService)
        aNetService.delegate = self
        aNetService.resolveWithTimeout(5.0)
    }


    func netServiceBrowser(browser: NSNetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
        print(errorDict)
    }

    func netServiceBrowser(browser: NSNetServiceBrowser, didRemoveService service: NSNetService, moreComing: Bool) {
        print("Service removed: \(service)")

    }

    func netService(sender: NSNetService, didNotResolve errorDict: [String : NSNumber]) {
        print(errorDict)
    }

    func netServiceDidResolveAddress(sender: NSNetService) {
        print(sender.addresses![0])
    }


}

【问题讨论】:

    标签: ios swift bonjour avahi nsnetservicebrowser


    【解决方案1】:

    您的问题的可能原因可能是您正在调用

    aNetService.resolveWithTimeout(5.0)
    

    在另一个函数中,所以只要

    didFindService
    

    完成,局部变量 aNetService 被销毁(因为它是 didFindService 函数的局部变量)

    解决方案

    我看到您已经在顶部定义了一个名为 "_service" 的具有类范围的变量 因此,使用

    _service = aNetService
    _service.resolveWithTimeout(5.0)
    

    在您的 didFindService 中 这应该可以解决您的问题。而且,现在应该调用 netServiceDidResolveAddress

    【讨论】:

    • 感谢 Aishwary 提供的好解决方案,但不幸的是,我没有通过您的解决方案获得正确的地址,所以我对代码进行了一些更改,现在它可以工作了。
    • 仍然有问题是 didFind 方法不是每次都在 iPhone 中被调用,但在 iPad 和模拟器中它每次都会被调用。我不知道为什么
    • func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool){ print("didRemoveService") if let ix = self.services.index(of: service) { self.services.remove(at: ix) print("removing a service") if !moreComing { self.updateInterface() } } }
    【解决方案2】:
    import Foundation
    class ServiceDiscovery : NSObject, NetServiceBrowserDelegate,NetServiceDelegate {
    
        var _browser:NetServiceBrowser!
        var _service: NetService!
        var services = [NetService]()
    
    
        func searchServices(){
            self.services.removeAll()
            _browser = NetServiceBrowser()
            _browser.delegate = self
            _browser.includesPeerToPeer = true
            _browser.searchForServices(ofType: "_https._tcp.", inDomain: "local.")
            _browser.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
        }
    
    
        func updateInterface () {
            for service in self.services {
                if service.port == -1 {
                    print("service \(service.name) of type \(service.type)" +
                        " not yet resolved")
                    service.delegate = self
                    service.resolve(withTimeout: 0.0)
                } else {
    
                    let deviceLanController = DeviceLanController()
                    let dict = NetService.dictionary(fromTXTRecord: service.txtRecordData()!)
                    let id = self.copyStringFromTXTDict(dict as [AnyHashable: Any]?, which: "id")
                    var ipAdd = ""
                    if let address = service.addresses{
                    if let addressOfFirstDevice = address.first{
                        let theAddress = addressOfFirstDevice as Data
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        if getnameinfo((theAddress as NSData).bytes.bindMemory(to: sockaddr.self, capacity: theAddress.count), socklen_t(theAddress.count),
                                       &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
                            if let numAddress = String(validatingUTF8: hostname) {
                                ipAdd = numAddress
                            }
                        }
    
                        if let serviceId = id{
                            deviceLanController.setDeviceAvailable(serviceId, host: ipAdd, port: "\(service.port)")
                        }
                    }
                    }
                }
            }
        }
    
    
        fileprivate func copyStringFromTXTDict(_ dict: [AnyHashable: Any]?, which: String) -> String? {
            // Helper for getting information from the TXT data
            var resultString: String? = nil
            if let data = dict?[which as NSObject] as! Data? {
                resultString = String(data: data, encoding: String.Encoding.utf8)!
    
            }
            return resultString
        }
    
    
    
        func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
            print("didFindDomain")
            print(domainString)
        }
    
        func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didFind aNetService: NetService, moreComing: Bool) {
            print("didFindService")
            self.services.append(aNetService)
            if !moreComing {
                aNetService.stop()
                self.updateInterface()
            }
        }
    
        func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool){
            print("didRemoveService")
            if let ix = self.services.index(of: service) {
                self.services.remove(at: ix)
                print("removing a service")
                if !moreComing {
                    self.updateInterface()
                }
            }
        }
    
        func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
            print("didNotSearch")
            print(errorDict)
        }
    
    
    
        func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
            print("didNotResolve",sender)
            print(errorDict)
    
        }
    
        func netServiceWillResolve(_ sender: NetService) {
            print("netServiceWillResolve",sender)
        }
        func netServiceDidResolveAddress(_ sender: NetService) {
            print("netServiceDidResolveAddress",sender)
           self.updateInterface()
        }
    
    }
    

    这个答案解决了我的问题。我正在解析并保存我的 coredata 中的每个地址,以便我可以使用该地址连接本地服务。

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 2021-08-14
      • 1970-01-01
      • 2015-11-19
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多