Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/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
Cocoa touch GCDAsyncSocket即使在断开连接后也无法多次接受端口_Cocoa Touch_Sockets_Gcdasyncsocket - Fatal编程技术网

Cocoa touch GCDAsyncSocket即使在断开连接后也无法多次接受端口

Cocoa touch GCDAsyncSocket即使在断开连接后也无法多次接受端口,cocoa-touch,sockets,gcdasyncsocket,Cocoa Touch,Sockets,Gcdasyncsocket,我希望能够关闭当前侦听端口的套接字,然后返回该套接字并在端口上重新建立侦听。我无法做到这一点,因为在另一个服务器侦听套接字上的第二个acceptOnPort调用总是以错误结束(地址已在使用)。如何关闭侦听套接字并重新建立一个新套接字?查看我刚才添加的 GCDAsyncSocket永远不会解除分配,因为dispatch_source_set_event_处理程序持有对块的引用,而该块持有对GCDAsyncSocket自身的引用 这导致无法关闭然后重新打开GCDAsyncSocket侦听器,因为该地

我希望能够关闭当前侦听端口的套接字,然后返回该套接字并在端口上重新建立侦听。我无法做到这一点,因为在另一个服务器侦听套接字上的第二个acceptOnPort调用总是以错误结束(地址已在使用)。如何关闭侦听套接字并重新建立一个新套接字?

查看我刚才添加的

GCDAsyncSocket永远不会解除分配,因为dispatch_source_set_event_处理程序持有对块的引用,而该块持有对GCDAsyncSocket自身的引用

这导致无法关闭然后重新打开GCDAsyncSocket侦听器,因为该地址已在使用中

这可以通过将引用更改为弱引用来解决。在dispatch\u source\u set\u event\u处理程序之前,添加以下行:

__弱GCDAsyncSocket*weakSelf=self

然后使用weakSelf而不是self调用doAccept

while([weakSelf-doAccept:socketFD]&&(++i 您需要重复两次,一次用于ipv4,一次用于ipv6

此时,您将发现GCDAsyncSocket从未解除分配是件好事,因为它会在运行解除分配后立即崩溃。这是因为dealloc调用closeWithError,后者反过来调用委托socketDidDisconnect,并将GCDAsyncSocket self作为参数传递。ARC立即保留GCDAsyncSocket,由于GCDAsyncSocket当前正在解除分配而崩溃

这可以通过将“delegate=nil”移动到dealloc的开头来解决,您也可以这样做,因为此时不可能安全地调用该委托(如果您希望能够通过GCDAsyncSocket,这是不可能的,您不能再这样做了)。另一种方法是在本例中调用socketdiddecast:nil

无论采用哪种方式,都意味着不会调用socketDidDisconnect,或者也不会使用适当的GCDAsyncSocket作为参数来调用socketDidDisconnect,这可能会破坏API契约,但在这一点上是不可避免的


更好的API应该是在dealloc发生之前使用某种“Kill”方法调用来杀死GCDAsyncSocket。

我做了您建议的“弱”更改,第二次尝试接受端口时仍然出错。我遗漏了什么吗?彼得,一旦我在随后的接收端口上引入了一点延迟,你的建议就行了。非常感谢。