我正在开发一个使用TCP连接到TCP服务器的iOS应用程序(使用Swift)。目前,每当我发送内容时,连接都会自动关闭。我想保持连接打开/活着,直到我手动关闭它。
从this Objective-C-based question我发现可以在Objective-C中这样做:
#include <sys/socket.h>
...
CFDataRef socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)(stream), kCFStreamPropertySocketNativeHandle);
CFSocketNativeHandle socket;
CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
CFRelease(socketData);
int on = 1;
if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
NSLog(@"setsockopt failed: %s", strerror(errno));
}
我目前的Swift实现/翻译如下:
var socketData = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySocketNativeHandle) as CFDataRef
var socket: CFSocketNativeHandle
CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8).self&socket)
var on: UInt8 = 1;
if setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, 255) == -1 {
}
一些注意事项:
inputStream
声明为:var inputStream: NSInputStream?
255
替代sizeof(on)
是个好主意。func stream(theStream:NSStream, handleEvent streamEvent:NSStreamEvent)
协议所需的函数NSStreamDelegate
中。inputStream
代替theStream
(函数参数)是个好主意。我在CFDataGetBytes
功能上遇到Xcode错误。它说:
&#39; NSData的&#39;不是&#39; CFData&#39;
的子类型
知道如何解决这个问题吗?
另外,如何在Swift文件中导入/包含<sys/socket.h>
?我已经看过一些叫做桥接标题的东西,但是不仅仅是Obj-C与Swift实现并排吗?
答案 0 :(得分:2)
CFDataRef
是NSData
的“免费桥接”,因此第一部分可以是
更简单地写成
var socketData = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySocketNativeHandle) as NSData
var socket: CFSocketNativeHandle = 0
socketData.getBytes(&socket, length: sizeofValue(socket))
setsockopt()
的“option_value”参数是int
的地址(映射到Swift为UInt32
),最后一个参数必须是该变量的大小:
var on: UInt32 = 1;
if setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, socklen_t(sizeofValue(on))) == -1 {
let errmsg = String.fromCString(strerror(errno))
println("setsockopt failed: \(errno) \(errmsg)")
}
<sys/socket.h>
默认导入。