Ios Swift:TCP套接字保持活动状态

Ios Swift:TCP套接字保持活动状态,ios,sockets,tcp,swift,Ios,Sockets,Tcp,Swift,我正在开发一个iOS应用程序(使用Swift),它使用TCP连接到TCP服务器。目前,无论何时我发送了内容,连接都会自动关闭。在手动关闭连接之前,我希望保持连接处于打开/活动状态 从中,我发现在Objective-C中可以这样做: #include <sys/socket.h> ... CFDataRef socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)(stream), kCFStreamPropert

我正在开发一个iOS应用程序(使用Swift),它使用TCP连接到TCP服务器。目前,无论何时我发送了内容,连接都会自动关闭。在手动关闭连接之前,我希望保持连接处于打开/活动状态

从中,我发现在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));
}
请注意:

  • inputStream
    声明为:
    var-inputStream:NSInputStream?
  • 我不确定使用
    255
    作为
    sizeof(on)
    的替代方案是否是个好主意
  • 代码发生在函数
    func流(流:NSStream,handleEvent流:nsstreamvent)
    中,这是使用
    NSStreamDelegate
    协议所必需的
  • 我不确定使用
    inputStream
    而不是
    theStream
    (函数参数)是否是个好主意
我在
CFDataGetBytes
函数中得到一个Xcode错误。它说:

“NSData”不是“CFData”的子类型

知道怎么解决吗

另外,如何在Swift文件中导入/包括
?我见过称为桥接头的东西,但这不只是针对Obj-C与Swift并行实现的吗?

CFDataRef
是“免费桥接”到
NSData
,因此第一部分可以 更简单地写为

var socketData = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySocketNativeHandle) as NSData
var socket: CFSocketNativeHandle = 0
socketData.getBytes(&socket, length: sizeofValue(socket))
setsockopt()
的“option\u 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)")
}

默认情况下导入。

TCP保持活动状态用于检测空闲连接上的错误。这无助于防止“自动关闭”。后者是一个应用程序问题,要在这里提供帮助,需要查看您的代码。谢谢您的回答。如果我获取的setsockopt失败:0x00007ff369887200,您知道该去哪里查找吗?也就是说,
setsockopt
函数返回-1。@eightx2:我已经更新了代码,以在故障情况下显示正确的错误号和消息。-手册页中列出了可能的错误号(“终端中的man setsockopt”,或)。@eightx2:您有什么进展吗?感谢更新。我收到以下错误:
setsockopt失败:22无效参数
。我了解到我必须只写
8
而不是
socklen_t(sizeofValue(on))
@eightx2:这意味着
UInt8
不是套接字选项的正确数据类型。C
int
映射到
Int32
,因此您可能必须使用
var on:UInt32=1
(以及
socklen\t(sizeofValue(on))
)。
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)")
}