为什么GCDAsyncSocket在读取超时后总是断开连接?

5
我查看了处理读取超时的代码 GCDAsyncSocket.m。如果我不延长超时时间,似乎套接字会关闭,并且没有选项使套接字保持活动状态。我无法使用无限超时(timeout = -1),因为我仍然需要知道何时超时,但也不希望它断开连接。我不确定是否有原因在其中。有人知道吗?
- (void)doReadTimeoutWithExtension:(NSTimeInterval)timeoutExtension
{
    if (currentRead)
    {
        if (timeoutExtension > 0.0)
        {
            currentRead->timeout += timeoutExtension;

            // Reschedule the timer
            dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeoutExtension * NSEC_PER_SEC));
            dispatch_source_set_timer(readTimer, tt, DISPATCH_TIME_FOREVER, 0);

            // Unpause reads, and continue
            flags &= ~kReadsPaused;
            [self doReadData];
        }
        else
        {
            LogVerbose(@"ReadTimeout");

            [self closeWithError:[self readTimeoutError]];
        }
    }
}

知道一下,https://github.com/robbiehanson/CocoaAsyncSocket/pull/126 上有一个拉取请求,添加了这个保活特性,但是还没有被合并。

1个回答

14
我是AsyncSocket的原始作者,我可以告诉你为什么我会这样做:协议处理超时有太多方法。因此,我实现了“硬”超时,并将“软”超时留给应用程序作者。
通常执行“软”超时的方法是使用NSTimerdispatch_after。设置其中之一,当计时器触发时,执行需要执行的操作。同时,在实际的readData调用中使用无限超时。请注意,无限超时并不是真正的无限。如果在10分钟内未成功读取,则操作系统仍然会超时。如果您真的想永远保持连接活动状态,可能可以设置套接字选项。

那么,为了做到这一点,你的意思是在代码中使用无限超时调用实际的readData,当我的软超时NSTimerdispatch_after触发时?只是确认一下 :) - Hlung
1
不,我的意思是使用无限超时实际执行readData,但同时设置NSTimerdispatch_after在软超时后触发。但我注意到,由其他人扩展和维护的最新版本的AsyncSocket具有一个委托调用,旨在让您更轻松地进行软超时。 - Donovan Voss
啊,谢谢你指出来。如果可能的话,你能给我一个那些仓库的例子吗?我在谷歌上搜索过,但是有很多结果,它们的描述看起来都一样。:/ - Hlung
nvm,我自己实现了软超时。这并不难。毕竟,我开始意识到软超时是套接字应该工作的方式,并且放弃了所有我的保持活动代码。再次感谢! - Hlung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接