作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我编写了这段代码来设置服务器流:
-(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
感谢您的帮助!
最佳答案
您可以通过以下方式获取 native 套接字句柄
CFDataRef socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)(inputStream), kCFStreamPropertySocketNativeHandle);
CFSocketNativeHandle socket;
CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
CFRelease(socketData);
然后设置套接字选项(为此你需要#include <sys/socket.h>
):
int on = 1;
if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
NSLog(@"setsockopt failed: %s", strerror(errno));
}
您可以将此代码放入 kCFStreamEventOpenCompleted
的事件处理函数中事件:
- (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 ... */;
}
}
关于ios - NSStream TCP 保活 iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15785917/
我是一名优秀的程序员,十分优秀!