2017-10-04 145 views
2

我嘗試建立到TCP服務器的連接,但不幸沒有成功。這是我實際的方式。有誰知道,錯誤在哪裏?我在CFSocketConnectToAddress(我得到.error結果,所以在連接打印時,我的代碼導致錯誤)。Swift中的CFSocket(4)

任何想法?

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") 
     } 

回答

0

問題是港口! 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 
}