Swift:TCP 套接字保持活动状态 [英] Swift: TCP socket keep-alive

查看:40
本文介绍了Swift:TCP 套接字保持活动状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 iOS 应用程序(使用 Swift),它使用到 TCP 服务器的 TCP 连接.目前,只要我发送了一些东西,连接就会自动关闭.我想保持连接打开/活动,直到我手动关闭它.

I'm developing an iOS app (using Swift) which uses a TCP connection to a TCP server. Currently, whenever I've sent something, the connection closes automatically. I want to keep the connection open/alive until I manually close it.

这个基于 Objective-C 的问题我发现可以做到在 Objective-C 中是这样的:

From this Objective-C-based question I found that it could be done like this in 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 实现/翻译如下所示:

My current Swift implementation/translation looks like this:

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(函数参数)是否是个好主意.
  • inputStream is declared as: var inputStream: NSInputStream?
  • I'm not sure if using 255 as an alternative to sizeof(on) is a good idea.
  • The code happens in the function func stream(theStream:NSStream, handleEvent streamEvent:NSStreamEvent) which is required by using the NSStreamDelegate protocol.
  • I'm not sure if using inputStream instead of theStream (function parameter) is a good idea.

我在 CFDataGetBytes 函数上遇到 Xcode 错误.它说如下:

I'm getting an Xcode error on the CFDataGetBytes function. It says the following:

'NSData' 不是 'CFData' 的子类型

'NSData' is not a subtype of of 'CFData'

知道如何解决这个问题吗?

Any idea how to fix that?

另外,如何在我的 Swift 文件中导入/包含 ?我见过一种叫做桥接标头的东西,但这不只是用于 Obj-C 与 Swift 实现并排的吗?

Also, how do I import/include <sys/socket.h> in my Swift file? I've seen something called bridging headers, but isn't that only for Obj-C side-by-side with Swift implementations?

推荐答案

CFDataRef 是免费桥接"到 NSData,因此第一部分可以是更简单的写成

CFDataRef is "toll-free bridged" to NSData, therefore the first part can be more simply written as

var socketData = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySocketNativeHandle) as NSData
var socket: CFSocketNativeHandle = 0
socketData.getBytes(&socket, length: sizeofValue(socket))

setsockopt() 的option_value"参数是 int 的地址(映射到 Swift 为 UInt32),并且最后一个参数必须是该变量的大小:

The "option_value" argument of setsockopt() is the address of an int (which is mapped to Swift as UInt32), and the last argument has to be the size of that variable:

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)")
}

是默认导入的.

这篇关于Swift:TCP 套接字保持活动状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆