Bonjour在iOS上发布

时间:2016-12-08 16:55:27

标签: ios swift sockets bonjour

我正在尝试在我的iOS应用程序中创建一个Bonjour服务,但无法将其发布。只调用了netServiceWillPublish委托方法,并且使用dns-sd没有显示该服务。

这是我的代码:

var service: NetService? = nil

func start() {
    createSockets()

    service = NetService(domain: "test", type: "_test._tcp.", name: "Test", port: Int32(port))
    service?.delegate = self
    service?.startMonitoring()
    service?.publish()
    service?.setTXTRecord(NetService.data(fromTXTRecord: [
        "model": "AppleTV3,2,1".data(using: .utf8)!,
        "srcvers": "160.10".data(using: .utf8)!,
        "features": "0x100009FF".data(using: .utf8)!,
        "deviceId": "b8:53:ac:43:f3:15".data(using: .utf8)!,
        "pw": "0".data(using: .utf8)!,
        "rmodel": "MacBookPro10,2".data(using: .utf8)!
        ]))

}

private func createSockets() {
    ipv4Socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAutomaticallyReenableAcceptCallBack, socketCallback, nil)

    var sin = sockaddr_in()

    memset(&sin, 0, MemoryLayout<sockaddr_in>.size)
    sin.sin_len = __uint8_t(MemoryLayout<sockaddr_in>.size)
    sin.sin_family = sa_family_t(AF_INET); /* Address family */
    sin.sin_port = in_port_t(port) /* Or a specific port */
    sin.sin_addr.s_addr = INADDR_ANY

    let sincfd = withUnsafePointer(to: &sin) {
        $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<sockaddr_in>.size) {
            return CFDataCreate(kCFAllocatorDefault, $0, MemoryLayout<sockaddr_in>.size)
        }
    }

    CFSocketSetAddress(ipv4Socket, sincfd)

    let socketsource = CFSocketCreateRunLoopSource(
        kCFAllocatorDefault,
        ipv4Socket,
        0);

    CFRunLoopAddSource(
        CFRunLoopGetCurrent(),
        socketsource,
        CFRunLoopMode.defaultMode);
}

我是iOS新手,我在这里做错了什么?

1 个答案:

答案 0 :(得分:4)

使用service?.publish(options: NetService.Options.listenForConnections)而不是自己创建套接字解决了这个问题。

最终以这种方式发布会自动为NetService的IPv4和IPv6创建TCP侦听器。

Apple文档:

/* When passed to -publishWithOptions:, in addition to publishing the service, a
 * TCP listener is started for both IPv4 and IPv6 on the port specified by the
 * NSNetService. If the listening port can't be opened, an error is reported using
 * -netService:didNotPublish:. Specify a port number of zero to use a random port.
 * When -netServiceDidPublish: is called, -port will return the actual listening
 * port number. Since the listener only supports TCP, the publish will fail with
 * NSNetServicesBadArgumentError if the NSNetService type does not end with "_tcp".
 * New incoming connections will be delivered in the form of NSStreams via the
 * -netService:didAcceptConnectionWithInputStream:outputStream: delegate method.
 */
 @available(iOS 7.0, *)
 public static var listenForConnections: NetService.Options { get }