Swift setsockopt SOL_SOCKET SO_RCVTIMEO获取无效参数

时间:2015-08-20 00:21:43

标签: swift sockets invalid-argument

以下游乐场演示了这个问题。

    //: 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)

任何帮助将不胜感激。

2 个答案:

答案 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" bindlisten,然后在结果上设置该选项,而不是在未连接的侦听器上设置。

其他随机互联网建议使用accept来处理时间问题。