我用Objective-C下面的代码,一个套接字写入数据。 该服务器运行在Ubuntu之上的node.js:
NSString *url = @"anIPAddress";
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)url, 9000, &readStream, &writeStream);
self.inputStream = (NSInputStream *)readStream;
self.outputStream = (NSOutputStream *)writeStream;
[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.inputStream open];
[self.outputStream open];
我能够连接到服务器并发送信息。 不过我注意到连接超时几分钟(我觉得5分钟左右?)之后。 我怎样才能继续保持该连接活着吗? 我知道有一个脱节,因为同样的事情发生,如果我连接到终端下的服务器,我必须保持该连接活着。 我想同样的事情在我的代码发生。 谢谢你的帮助!
最简单的答案是尝试使用SO_KEEPALIVE
套接字选项。
残破的连接可以是硬没有终点是什么使得在某些方面没用,因为它不使用数据来检测断开的连接此选项之间的数据流检测。 然而,很容易添加到您的代码,看看。 添加它,看看是否有帮助?
这是它是如何在C或C ++进行
int opt = 1;
// Get the native socket handle from your socket class here...
int socket_handle = getNativeSocketHandle( self.outputStream );
/*Enabling keep alive*/
if( setsockopt( socket_handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof( opt ) ) < 0 )
{
// failed setting socket option
}
在不那么简单的答案是一个添加ping
包到您的协议,并定期发送ping包,所以你可以检测断开的连接。
我发现如何做到这一点。 由于服务器正在运行的node.js,我用
socket.setKeepAlive(true, 2000);
而在这样的节点保持每个插座打开。 默认是假的,所以这就是为什么它被超时。 我希望这是对别人有用。 感谢您为您的答复,我想保持心跳(保持活动)也是一个不错的想法,但这种做法本地节点照顾它。
假设NSOutputStream *的ostream;
在iOS做这种方式:
#if 1 // Using CF
CFDataRef data = (CFDataRef)CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)oStream, kCFStreamPropertySocketNativeHandle);
if(data) {
CFSocketNativeHandle socket_handle = *(CFSocketNativeHandle *)CFDataGetBytePtr(data);
CFRelease(data);
#else // Using Foundation
NSData *data = (NSData *)[oStream propertyForKey:(__bridge NSString *)kCFStreamPropertySocketNativeHandle];
if(data) {
CFSocketNativeHandle socket_handle = *(CFSocketNativeHandle *)[data bytes];
#endif
NSLog(@"SOCK HANDLE: %x", socket_handle);
/*Enabling keep alive*/
if( setsockopt( socket_handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof( opt ) ) < 0 )
{
NSLog(@"Yikes 2: failed to set keepalive! ERRNO: %s", strerror(errno));
}
因为我只花了几个小时了这一切,要保存别人的努力,我张贴这一点。
你需要定期发送一些垃圾上的连接。 试试这个:
NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:240 target:self selector:@selector(timerMethod:) userInfo:[NSNumber numberWithInt:sockfd] repeats:YES];
然后,在此声明self
:
-(void)timerMethod:(NSTimer*)t
{
send([[t userInfo] intValue], "Keepalive!", 11, 0);
}
注意:更换`“保持连接!” 不管你想为您的协议。 唯一的要求是,所述远端(套接字服务器)忽略该消息。