问题描述
我已编写此代码以使用服务器设置流:
I have written this code to setup a stream with a server:
-(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路由器断开电缆,我仍然可以在流中发送数据并且没有发生错误。
I am able to connect to the server and send & receive data. But I want to check if the connection is still there. If I disconnect a cable from the wifi router, I still can send data in the stream and no error occurred.
您可以通过使用计时器在应用程序级别解决此问题。发送一些消息并检查您是否收到回复的信息。但是你也可以用较低级别的TCP Keep-Alive技术解决这个问题。
You can solve this on application level by using a timer to send some message and check if you receive something back. But you can solve this also with TCP Keep-Alive technique on a lower level.
如何用NSStream实现这个?如何设置检查间隔?
How do I implement this with NSStream? How can I set the checking interval?
我假设您通过使用TCP Keep-Alive检查流来关闭流时会得到NSStreamEventErrorOcurred?
I assume that you get a NSStreamEventErrorOcurred when the stream is down by checking it with TCP Keep-Alive?
我已经查过这篇文章,但我无法弄明白:
I have checked this post, but I can't figure it out:Keeping a socket connection alive in iOS
感谢您的帮助!
推荐答案
您可以使用
CFDataRef socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)(inputStream), kCFStreamPropertySocketNativeHandle);
CFSocketNativeHandle socket;
CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
CFRelease(socketData);
然后设置套接字选项(你需要 #include< sys / socket.h>
for this):
and then set socket options (you need to #include <sys/socket.h>
for this):
int on = 1;
if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
NSLog(@"setsockopt failed: %s", strerror(errno));
}
您可以将此代码放在<$ c $的事件处理函数中c> kCFStreamEventOpenCompleted 事件:
You could put this code in the event handler function for the kCFStreamEventOpenCompleted
event:
- (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 ... */;
}
}
这篇关于NSStream TCP Keep-alive iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!