我尝试建立与TCP服务器的连接,不幸的是没有成功。这是我的实际方式。有人知道,错误在哪里吗?我在 CFSocketConnectToAddress
处遇到错误(我得到.ERROR结果,因此我的代码在连接打印时会导致错误)。
有什么想法?
host = "192.168.0.20"
port = 8888
socket = CFSocketCreate(kCFAllocatorDefault,
AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
CFSocketCallBackType.readCallBack.rawValue, { (socket: CFSocket?, callBackType: CFSocketCallBackType, address: CFData?, data: UnsafeRawPointer?, info: UnsafeMutableRawPointer?) -> Void in print("callback test") }, nil)
if socket == nil {
print("Error while creating socket")
} else {
var sin = sockaddr_in(
sin_len: UInt8(MemoryLayout<sockaddr_in>.size),
sin_family: sa_family_t(AF_INET),
sin_port: in_port_t(port),
sin_addr: in_addr(s_addr: inet_addr(host)),
sin_zero: (0,0,0,0,0,0,0,0)
)
addressData = NSData(bytes: &sin, length: MemoryLayout.size(ofValue: sin)) as CFData
let connectResult: CFSocketError = CFSocketConnectToAddress(socket, addressData!, 10)
switch connectResult {
case .success:
print("Connected")
case .error:
print("Error while connecting")
case .timeout:
print("Timeout while connecting")
}
问题是端口!htons
宏在Swift中不可用。这是现在的工作方式:
func connectToServer(timeout: Int=10) throws {
// check, if address is valid https://linux.die.net/man/3/inet_makeaddr
let inAddr = inet_addr(host)
if inAddr == INADDR_NONE {
throw SocketError.noValidAddress
}
let socket = CFSocketCreate(kCFAllocatorDefault,
AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
CFSocketCallBackType.readCallBack.rawValue,
{ (socket, callBackType, address, data, info) in
TCPClientCallBack(socket: socket, callBackType: callBackType, address: address, data: data, info: info)
},
nil)
if socket == nil {
throw SocketError.socketCreationFailed
}
var sin = sockaddr_in() // https://linux.die.net/man/7/ip
sin.sin_len = __uint8_t(MemoryLayout.size(ofValue: sin))
sin.sin_family = sa_family_t(AF_INET)
sin.sin_port = UInt16(port).bigEndian
sin.sin_addr.s_addr = inAddr
let addressDataCF = NSData(bytes: &sin, length: MemoryLayout.size(ofValue: sin)) as CFData
let socketErr = CFSocketConnectToAddress(socket, addressDataCF, CFTimeInterval(timeout))
switch socketErr {
case .success:
print("connected")
case .error:
throw SocketError.connectionError
case .timeout:
throw SocketError.connectionTimeout
}
}
enum SocketError: Error {
case noValidAddress
case socketCreationFailed
case connectionError
case connectionTimeout
}