以下游乐场演示了这个问题。
//: Playground - noun: a place where people can play
import Foundation
var s = socket(AF_INET, SOCK_STREAM, 0)
var tv = timeval()
tv.tv_sec = 3
tv.tv_usec = 100000
let tvSize = socklen_t(sizeof(timeval))
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, tvSize)
NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
结果是setsockopt()
得-1,NSError返回EINVAL
Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument"
这是Mac OS X 10.11,xcode版本7.0 beta 5(7A176x)
任何帮助将不胜感激。
答案 0 :(得分:0)
海报在Apple论坛和Apple工程师responded with details中提出了同样的问题。
解决方案的要点是,为了与C API进行互操作,您通常需要使用strideof(T)
,它以与C sizeof()
运算符相同的方式考虑尾随结构填充。更常用的sizeofValue()
不会这样做。
在sizeofValue(timeval)
和strideof(timeval)
均为8的32位模型(即iPhone 5)上运行时,此问题无法显现。
在64位模型上,相应的大小为12和16,当传递12而不是预期的16时,导致O / S向EINVAL
投诉。
答案 1 :(得分:-2)
这实际上不是Swift问题。与SO_相关的选项很挑剔。 OpenGroup.org说:
http://pubs.opengroup.org/onlinepubs/009695399/functions/setsockopt.html
请注意,并非所有实现都允许设置此选项。
在这种情况下,Linux& Mac OS X同意:在套接字处于连接状态之前,你不能这样做,例如for TCP:for a in *; do :; done; echo "$a"
,bind
,listen
,然后在结果上设置该选项,而不是在未连接的侦听器上设置。
其他随机互联网建议使用accept
来处理时间问题。