Swift 中创建的 CFSocket 未监听

CFSocket created in Swift not listening

我正在尝试使用 a 2012 WWDC session 中的示例代码启动和 运行 基本的 Bonjour 发现,但已将其转换为 Swift。它部分工作。我能够注册一个端口,并在该端口上注册我的服务。客户端能够发现并解析该服务。

问题是:我调用了 CFSocketCreateWithNative() 并指定了回调侦听器,但该回调从未被调用过。此外,我尝试使用 telnet (telnet localhost 12345) 连接,我得到:

Trying ::1...

telnet: connect to address ::1: Connection refused

Trying 127.0.0.1...

telnet: connect to address 127.0.0.1: Connection refused

Trying fe80::1...

telnet: connect to address fe80::1: Connection refused

telnet: Unable to connect to remote host

这是我如何注册套接字的简化版本,包含完整的 Swift 文件 in a Gist:

private func registerIPv4Socket() throws -> (Int32, in_port_t) {
    let fd4 = socket(AF_INET, SOCK_STREAM, 0)

    var sin = sockaddr_in()
    sin.sin_family = sa_family_t(AF_INET)
    sin.sin_len = UInt8(sizeofValue(sin))
    sin.sin_port = 0

    withUnsafePointer(&sin) {
        Foundation.bind(fd4, UnsafePointer([=11=]), UInt32(sin.sin_len))
    }

    var addrLen = socklen_t(sizeofValue(sin))
    withUnsafeMutablePointers(&sin, &addrLen) { (sinPtr, addrPtr) -> Int32 in
        getsockname(fd4, UnsafeMutablePointer(sinPtr), UnsafeMutablePointer(addrPtr))
    }

    let listenError = listen(fd4, 5)        
    return (fd4, sin.sin_port)
}

private func registerIPv6Socket(port: in_port_t) throws -> Int32 {
    let fd6 = socket(AF_INET6, SOCK_STREAM, 0)

    var one: Int32 = 1
    withUnsafePointer(&one) {
        setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, UnsafePointer([=11=]), socklen_t(sizeofValue(one)))
    }

    var sin6 = sockaddr_in6()
    sin6.sin6_family = sa_family_t(AF_INET6)
    sin6.sin6_len = UInt8(sizeofValue(sin6))
    sin6.sin6_port = port

    withUnsafePointer(&sin6) {
        Foundation.bind(fd6, UnsafePointer([=11=]), UInt32(sin6.sin6_len))
    }

    var addrLen = socklen_t(sizeofValue(sin6))
    withUnsafeMutablePointers(&sin6, &addrLen) { (sinPtr, addrPtr) -> Int32 in
        getsockname(fd6, UnsafeMutablePointer(sinPtr), UnsafeMutablePointer(addrPtr))
    }

    listen(fd6, 5)
    return fd6
}

为什么我的应用程序没有在它报告的端口上侦听?

您的 IPv4 套接字正在侦听端口 sin.sin_port.bigEndian,但您的 IPv6 套接字正在侦听小端端口。更新您的 IPv6 代码以使用大端端口:

sin.sin6_port = port.bigEndian