我正在尝试构建一个可以使用纯Swift代码创建TCP连接的类。 Everything编译文件,但是当下面的代码运行时,我在调用getaddrinfo
函数时遇到EXC_BAD_ACCESS崩溃。
尝试在servInfo
函数的最后一个参数中引用getaddrinfo
变量时发生崩溃。我浏览了网页,看来我声明UnsafeMutablePointer变量是正确的,因为它需要由getaddrinfo
函数设置。
有没有人有任何想法发生了什么?我正在使用最新的Swift 3快照构建。
import Darwin
import Foundation
class SwiftTcp {
//MARK: - Properties
var serviceAddress = "0.0.0.0"
var servicePort: Int = 8080
//MARK: - Read-only properties
private(set) var status: Int32 = 0
//MARK: - Private variables
// protocol configuration
private var hints = addrinfo(
ai_flags: AI_PASSIVE,
ai_family: AF_UNSPEC,
ai_socktype: SOCK_STREAM,
ai_protocol: 0,
ai_addrlen: 0,
ai_canonname: nil,
ai_addr: nil,
ai_next: nil)
// used to set the protocol info needed to make a socket connection
private var servInfo: UnsafeMutablePointer<addrinfo> = nil
//MARK: - Initialization
deinit {
freeaddrinfo(servInfo)
}
init() {
SwiftLog.trace("[SwiftTcp][Connect] Initialize...")
// get protocol info
status = getaddrinfo(
nil,
UnsafePointer<Int8>(bitPattern: servicePort),
&hints,
&servInfo)
if (status != 0) {
let err = String(UTF8String: gai_strerror(status)) ?? "Unknown error code"
SwiftLog.error("Unable to get address information: Error \(err)")
return
}
#if DEBUG
var info = servInfo
repeat {
let (clientIp, service) = sockaddrDescription(info.memory.ai_addr)
let message = "HostIp: " + (clientIp ?? "?") + " at port: " + (service ?? "?")
SwiftLog.debug(message)
// get next or nil
info = nil
info = info.memory.ai_next
} while info != nil
#endif
}
func connect() {
// do nothing
}
//MARK: - Private Helpers
private func sockaddrDescription(addr: UnsafePointer<sockaddr>) -> (String?, String?) {
var host : String?
var service : String?
var hostBuffer = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
var serviceBuffer = [CChar](count: Int(NI_MAXSERV), repeatedValue: 0)
if getnameinfo(
addr,
socklen_t(addr.memory.sa_len),
&hostBuffer,
socklen_t(hostBuffer.count),
&serviceBuffer,
socklen_t(serviceBuffer.count),
NI_NUMERICHOST | NI_NUMERICSERV)
== 0 {
host = String(UTF8String: hostBuffer)
service = String(UTF8String: serviceBuffer)
}
return (host, service)
}
}
答案 0 :(得分:2)
中的第二个参数
status = getaddrinfo(
nil,
UnsafePointer<Int8>(bitPattern: servicePort),
&hints,
&servInfo)
当你输出数字8080
时,毫无意义并导致崩溃 指针。
getaddrinfo()
需要一个C字符串(Swift中为UnsafePointer<Int8>
),
但你可以简单地传递一个Swift字符串,这是自动的
转换(如String value to UnsafePointer<UInt8> function parameter behavior中所述):
let servicePort = "8080"
status = getaddrinfo(
nil,
servicePort,
&hints,
&servInfo)