如何在iOS中快速获取由AVAHI发布的服务的IP和PORT?
问题描述:
我正在使用NSNetServiceBrowser并能够在“didFindService”中找到由AVAHI发布的服务列表,如下所示: 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B9ED382 -1 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B8E3916 -1 服务出现:本地。 _https._tcp。 TEMP-Mobileyes5-1C497B9ED380 -1如何在iOS中快速获取由AVAHI发布的服务的IP和PORT?
但无法找到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])
}
}
答
可能的原因您的问题可能是您所呼叫的
aNetService.resolveWithTimeout(5.0)
另一个函数内部,使其尽快作为
didFindService
结束,局部变量aNetService被销毁(因为它是didFindService福局部变量nction)
SOLUTION
我看到你已经在一个名为“_Service” 因此类范围广顶部定义变量,可以使用通过使用
_service = aNetService
_service.resolveWithTimeout(5.0)
你的didFindService 这应该可以解决你的问题。而且,netServiceDidResolveAddress现在应该被调用。
答
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中的每个地址,以便我可以使用该地址连接本地服务。
谢谢你的很好的解决方案Aishwary,但不幸的是我没有用您的解决方案得到正确的地址,所以我没有在我的代码一些变化,现在它的工作。 –
仍然存在的问题是didFind方法在iPhone中每次都不会被调用,但在iPad和模拟器中每次都会调用它。我不知道为什么 –
'func netServiceBrowser(_浏览器:NetServiceBrowser,didRemove服务:NetService,moreComing:布尔){ print(“didRemoveService”)如果让ix = self.services.index(of:service) (在ix) 打印 –