2017-06-29 100 views
2

我一直在試圖建立一個連接到本地文件的連接,但錯誤號總是返回-1連接到本地套接字

var socketPath = "/path/to/socket" 

let sockDesc = socket(AF_LOCAL, SOCK_STREAM, 0) 

var address = sockaddr_un() 
address.sun_family = UInt8(AF_LOCAL) 
address.sun_len = UInt8(bitPattern:Int8(MemoryLayout<sockaddr_un>.size)) 

let dataPtr = UnsafeMutablePointer<Int8>(&address.sun_path.0) 
strncpy(dataPtr, socketPath, socketPath.characters.count) 

let result = withUnsafePointer(to: &address) { 
    $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { 

     connect(sockDesc, $0, socklen_t(MemoryLayout<sockaddr>.stride)); 
    } 
} 

插座是有效的,因爲其他客戶端,在Qt的開發可以愉快地連接到這條路。

這裏有明顯的錯誤,還是應該這樣工作?

回答

3

connect()第三個參數必須是sockaddr_un的實際大小 ,不是的「通用」 sockaddr。 有了一些小的簡化:

var socketPath = "/path/to/socket" 

let sockDesc = socket(AF_LOCAL, SOCK_STREAM, 0) 
var address = sockaddr_un() 
address.sun_family = UInt8(AF_LOCAL) 
address.sun_len = UInt8(MemoryLayout<sockaddr_un>.size) 
strlcpy(&address.sun_path.0, socketPath, MemoryLayout.size(ofValue: address.sun_path)) 

let result = withUnsafePointer(to: &address) { 
    $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { 
     connect(sockDesc, $0, socklen_t(address.sun_len)); 
    } 
} 

還要注意

strncpy(dataPtr, socketPath, socketPath.characters.count) 
在你的代碼拷貝

socketPath.characters.count字節 dataPtr,這是錯誤的,原因如下:

  • socketPath.characters.count不是如果字符串包含非ASCII字符,則爲UTF-8字節數 ,
  • 它不保證目標字符串是空終止的,它可能會覆蓋目標緩衝區。

strncpy()是很容易被濫用,並strlcpy()(如果有的話)是 往往是一個更好的選擇。

+0

謝謝,這正是我正在尋找和很好地瞭解strlcpy。 – TheDarkKnight