Swift中的CFSocket(4)

时间:2017-10-04 06:04:41

标签: swift cfsocket

我尝试建立与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")
        }

1 个答案:

答案 0 :(得分:1)

问题是端口! 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
}