Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.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
Ios 如何确保服务器端CFSocket在应用程序退出并再次返回活动状态后侦听?_Ios_Iphone_Sockets_Cfsocket - Fatal编程技术网

Ios 如何确保服务器端CFSocket在应用程序退出并再次返回活动状态后侦听?

Ios 如何确保服务器端CFSocket在应用程序退出并再次返回活动状态后侦听?,ios,iphone,sockets,cfsocket,Ios,Iphone,Sockets,Cfsocket,我有一个iOS应用程序,大致遵循以下步骤: 打开侦听套接字。 接受单个客户端连接。 执行与客户端之间的数据交换。 当接收到退出活动事件时,它关闭并释放与客户端和服务器套接字相关的所有资源,即使所有运行循环源、读/写流和套接字本身失效并释放。 在恢复活动状态时,它会恢复侦听套接字以继续通信。在iOS应用程序在步骤4中退出活动状态后,客户端将继续尝试重新连接,直到能够重新连接为止。 每当客户端和服务器之间发生连接时,我在步骤5之后看到的是,应用程序将恢复,而无法重新打开服务器套接字进行侦听。换句话说

我有一个iOS应用程序,大致遵循以下步骤:

打开侦听套接字。 接受单个客户端连接。 执行与客户端之间的数据交换。 当接收到退出活动事件时,它关闭并释放与客户端和服务器套接字相关的所有资源,即使所有运行循环源、读/写流和套接字本身失效并释放。 在恢复活动状态时,它会恢复侦听套接字以继续通信。在iOS应用程序在步骤4中退出活动状态后,客户端将继续尝试重新连接,直到能够重新连接为止。 每当客户端和服务器之间发生连接时,我在步骤5之后看到的是,应用程序将恢复,而无法重新打开服务器套接字进行侦听。换句话说,即使在步骤5中发布了所有内容,应用程序也无法重新绑定并侦听套接字地址。更糟糕的是,在尝试重新设置侦听套接字时,在cfsocketapi调用中无法检测到错误

另一方面,如果iOS应用程序退出活动状态并再次恢复,而之前没有收到任何连接,则客户端可以只连接一次,直到应用程序退出并再次恢复,在这种情况下,可以观察到上述相同的行为

可以在以下存储库中找到说明此问题的示例应用程序:

最相关的资料来源是:

导入AppDelegate.h 进口 进口 进口 静态void\u handleConnectCFSocketRef套接字,CFSocketCallBackType类型,CFDataRef地址,const void*数据,void*信息 { NSLog@Connected ...; 关闭*CFSocketNativeHandle*数据; NSLog@Closed ...; } @接口AppDelegate @结束 @实现AppDelegate{ CFRunLoopSourceRef\u源; CFSocketRef_serverSocket; CFRunLoopRef_socketRunLoop; } -voidapplicationWillResignActive:UIApplication*应用程序{ CFRunLoopRemoveSourceself->_socketrunlop,self->_source,kCFRunLoopCommonModes; CFRunLoopSourceInvalidateself->\u源; CFReleaseself->\u来源; self->_source=nil; CFSocketInvalidateself->\u服务器套接字; CFReleaseself->\u服务器插座; self->_serverSocket=nil; CFRunLoopStopself->\u socketRunLoop; NSLog@RELASED成功地 } -voidApplicationIDBecomeActive:UIApplication*应用程序{ CFSocketContext ctx={0,_桥空*self,NULL,NULL,NULL}; self->_serverSocket=cfsocketcreatekcfalocatordefault, PF_INET, 苏克河, IPPROTO_TCP, kCFSocketAcceptCallBack、_handleConnect和ctx; NSLog@Socket已创建%u,self->\u serverSocket!=NULL; sin中的结构sockaddr_; memset&sin,0,sizeofsin; sin.sin_len=sizeofsin; sin.sin_family=AF_INET; sin.sin_端口=hton30000; sin.sin\u addr.s\u addr=INADDR\u ANY; CFDataRef sincfd=cfdatacreatekcfolcatordefault, UInt8*和sin, sizeofsin; CFSocketSetAddressself->\u服务器套接字,sincfd; cfd释放cfd; self->_source=CFSocketCreateRunLoopSourcekCFAllocatorDefault, self->\u服务器插座, 0; NSLog@Created源%u,自->\u源!=NULL; self->_socketRunLoop=CFRunLoopGetCurrent; CFRunLoopAddSourceself->\u socketRunLoop, 自我->\u来源, kCFRunLoopCommonModes; NSLog@Registered进入运行循环; NSLog@Socket%s,CFSocketIsValidself->\u serverSocket?有效:无效; NSLog@Source是否为%s,CFRunLoopSourceIsValidself->\u源?有效:无效; }
@end这里的问题是侦听套接字将进入TIME_WAIT,并且在该状态下无法再次绑定

即使cfsocketapi没有返回错误,如果在使用POSIX套接字时发生相同的情况,那么在尝试重新绑定套接字时也会发生错误


解决方案是在重新绑定套接字进行监听之前,简单地为套接字设置SO_REUSEADDR选项。

并删除CFSocket以支持POSIX网络/线程