Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在iOS中保持套接字连接的活动状态_Objective C_Sockets_Ios5_Timeout_Keep Alive - Fatal编程技术网

Objective c 在iOS中保持套接字连接的活动状态

Objective c 在iOS中保持套接字连接的活动状态,objective-c,sockets,ios5,timeout,keep-alive,Objective C,Sockets,Ios5,Timeout,Keep Alive,我用Objective-C编写了以下代码,将数据写入套接字。服务器正在Ubuntu上运行node.js: NSString *url = @"anIPAddress"; CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)url, 9000, &readStream, &

我用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\u KEEPALIVE
socket选项

如果端点之间没有数据流动,断开的连接可能很难检测,这使得此选项在某些方面毫无用处,因为它不使用数据来检测断开的连接。但是,很容易添加到代码中查看。添加它,看看它是否有帮助

这是在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
}
int opt=1;
//在此处从套接字类获取本机套接字句柄。。。
int socket_handle=getNativeSocketHandle(self.outputStream);
/*保持活力*/
if(setsockopt(socket\u句柄、SOL\u socket、SO\u KEEPALIVE、&opt、sizeof(opt))小于0)
{
//设置套接字选项失败
}

不那么简单的答案是将一个
ping
数据包添加到您的协议中,并定期发送该ping数据包,这样您就可以检测到断开的连接。

您需要定期通过连接发送一些垃圾。试试这个:

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

注意:将“Keepalive!”替换为协议所需的任何内容。唯一的要求是远程端(套接字服务器)忽略该消息。

我找到了如何做到这一点。因为服务器正在运行node.js,所以我使用了

socket.setKeepAlive(true, 2000);

通过这种方式,node使每个套接字保持打开状态。默认值为false,这就是它超时的原因。我希望这对其他人有用。感谢您的回复,我认为保持心跳(保持活动状态)也是一个好主意,但使用此本机方法,节点会处理它。

假设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));
    }
#如果1//使用CF
CFDataRef data=(CFDataRef)CFWriteStreamCopyProperty((uu桥CFWriteStreamRef)oStream,kCFStreamPropertySocketNativeHandle);
如果(数据){
CFSocketNativeHandle套接字\ U句柄=*(CFSocketNativeHandle*)CFDataGetBytePtr(数据);
发布(数据);
利用其他基础
NSData*数据=(NSData*)[oStream PropertyWorkey:(uu bridge NSString*)kCFStreamPropertySocketNativeHandle];
如果(数据){
CFSocketNativeHandle套接字\ U句柄=*(CFSocketNativeHandle*)[数据字节];
#恩迪夫
NSLog(@“套接字句柄:%x”,套接字句柄);
/*保持活力*/
if(setsockopt(socket\u句柄、SOL\u socket、SO\u KEEPALIVE、&opt、sizeof(opt))小于0)
{
NSLog(@“Yikes 2:设置keepalive失败!错误号:%s”,strerror(ERRNO));
}


我之所以发布这篇文章,是因为我花了几个小时来完成这一切,想省去其他人的精力。

是否有一个设定的超时限制?我想知道我应该以什么频率发送垃圾数据。@用户:连接需要多长时间才能断开?在这之前安排一点。在某些情况下,不要使用“垃圾”你可能会认为这是“心跳数据”在socket服务器上。向上投票!:)@Linuxios:什么是sockfd?@tonygil:我使用的是URL而不是IP地址。会有问题吗?还有,我如何解决它?嗯。有没有办法使用上面Objective-C中的API来实现这一点?@Hahnemann:我不太了解Objective-C,所以我不知道。不过,我愿意打赌有一个逃生舱来进行调用o C libs@Hahnemann:看看这里,看看是否有帮助。@JimR:我收到一条错误消息:“设置keepalive失败!错误号:非套接字上的套接字操作”可能的原因和可能的解决方案是什么?嗨,getNativeSocketHandle()是什么您从ios streams开始,现在正在使用socket对象?您在这里使用的是什么类型的api?@ItayLevin他正在向您展示他是如何在服务器上实现的-请参阅下面我的答案,了解如何在ios上实现它。socket_handle、SOL_socket和SO_KEEPALIVE的值是多少?man 2 setsockopt或在Xcode文档vie中搜索setsockoptw、 只有苹果能做这么简单,这么复杂的事情。我用Berkley Sockets编写了网络应用程序,比这个简单。需要在哪里编写这个方法?@Hardikmatora,就在你得到输出流的引用之后。有关有效的Objective-C代码,请参阅。。。