首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSStream TCP Keep-alive iOS

NSStream TCP Keep-alive iOS
EN

Stack Overflow用户
提问于 2013-04-03 19:20:06
回答 2查看 7.7K关注 0票数 5

我已经编写了以下代码来设置带有服务器的流:

代码语言:javascript
复制
-(void)streamOpenWithIp:(NSString *)ip withPortNumber:(int)portNumber;
{
       CFReadStreamRef readStream;
       CFWriteStreamRef writeStream;
       CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)ip, portNumber, &readStream, &writeStream);

       if(readStream && writeStream)
       {
            CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
            CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

            //Setup inpustream
            inputStream = (__bridge NSInputStream *)readStream;
            [inputStream setDelegate:self];
            [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [inputStream open];

            //Setup outputstream
            outputStream = (__bridge NSOutputStream *)writeStream;
            [outputStream setDelegate:self];
            [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream open];
       }
}

我能够连接到服务器并发送和接收数据。但我想检查连接是否还在那里。如果我断开与wifi路由器的电缆连接,我仍然可以在流中发送数据,并且没有发生错误。

您可以通过使用计时器发送一些消息并检查是否收到回执,从而在应用程序级别解决此问题。但您也可以在较低级别上使用TCP Keep-Alive技术来解决此问题。

我如何用NSStream实现这一点?如何设置检查间隔?

我假设您可以通过使用TCP Keep-Alive检查流关闭时获得NSStreamEventErrorOcurred?

我已经看过这篇文章了,但我想不通:Keeping a socket connection alive in iOS

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

发布于 2013-04-03 20:14:05

您可以使用以下命令获取本机套接字句柄

代码语言:javascript
复制
CFDataRef socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)(inputStream), kCFStreamPropertySocketNativeHandle);
CFSocketNativeHandle socket;
CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
CFRelease(socketData);

然后设置套接字选项(您需要为此使用#include <sys/socket.h>命令):

代码语言:javascript
复制
int on = 1;
if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
   NSLog(@"setsockopt failed: %s", strerror(errno));
}

您可以将此代码放入kCFStreamEventOpenCompleted事件的事件处理函数中:

代码语言:javascript
复制
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
    switch (event) {
        case kCFStreamEventOpenCompleted:
            if (stream == self.inputStream) {
                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));
                }
            }
            break;

        /* ... other cases ... */;
    }
}
票数 12
EN

Stack Overflow用户

发布于 2015-12-15 23:22:28

对于类似的问题,有一个更完整的答案。

有关该应用程序的示例,该应用程序在10秒后开始发送keepalive,每2秒发送一次keppalive,并在4次keepalives后关闭流,但没有回复,请查看此帖子:Is it possible to activate TCP keepalive on Apple iOS devices

还说明了如何设置连接关闭前的重传超时。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15785917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档