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
我正在尝试使用 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