swift - 连接到本地套接字

标签 swift sockets

我一直在尝试创建到本地套接字文件的连接,但 errno 总是返回 -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开发的客户端可以愉快地连接到这个路径。

这里有明显的错误吗,或者这应该行得通吗?

最佳答案

connect()的第三个参数必须是实际大小 sockaddr_un 的,而不是“通用”sockaddr 的。 通过一些小的简化:

let 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 socklen = socklen_t(address.sun_len)

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

还要注意

strncpy(dataPtr, socketPath, socketPath.characters.count)

在您的代码中将 socketPath.characters.count 字节复制到 dataPtr,错误的原因有几个:

  • socketPath.characters.count 不是UTF-8字节数 如果字符串包含非 ASCII 字符,
  • 它不保证目标字符串以 null 结尾,
  • 它可能会覆盖目标缓冲区。

strncpy() 很容易被误用,strlcpy()(如果可用)是 通常是更好的选择。

关于swift - 连接到本地套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44823477/

相关文章:

c# - C#连续套接字监听

swift - PKAddPaymentPassViewController 为零

ios - 自定义键盘 - 长按键盘按钮时添加多个表情符号图标

swift - 点击时更改按钮的文本颜色

json - 如何使用 Alamofire 恢复活力

python - 线程UDP套接字

c - 带有 epoll 和线程的套接字服务器

php - 是否可以重新使用故意打开的套接字?

IOS - 运行后台任务以使用 swift 更新用户位置

linux - ARP 表在 send() 调用期间/期间更改的影响