简体   繁体   English

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

[英]Why GCDAsyncSocket always disconnect afters read timeout?

I looked into GCDAsyncSocket.m at the code that handles read timeout. 我在处理读取超时的代码中查看了GCDAsyncSocket.m。 If I don't extend the timeout, it seems that socket got closed and there is no option to the socket alive keep. 如果我没有延长超时,似乎套接字已关闭,并且套接字没有选项保持。 I can't use infinite timeout (timeout = -1) because I still need to know when it is timed out, but also doesn't want it to disconnect. 我不能使用无限超时(超时= -1),因为我仍然需要知道它何时超时,但也不希望它断开连接。 I'm not sure there is a reason behind this. 我不确定这背后有什么原因。 Does anyone know? 有人知道吗?

- (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]];
        }
    }
}

FYI, there is a pull request at https://github.com/robbiehanson/CocoaAsyncSocket/pull/126 that adds this keep-alive feature but it is not pulled yet. 仅供参考, https://github.com/robbiehanson/CocoaAsyncSocket/pull/126上有一个拉取请求,它添加了这个保持活动的功能,但尚未提取。

I am the original author of AsyncSocket, and I can tell you why I did it that way: there are too many ways for protocols to handle timeouts. 我是AsyncSocket的原作者,我可以告诉你为什么我这样做:协议处理超时的方法太多了。 So I implemented a "hard" timeout and left "soft" timeouts up to the application author. 所以我实现了一个“硬”超时并将“软”超时留给了应用程序作者。

The usual way to do a "soft" timeout is with an NSTimer or dispatch_after . 执行“软”超时的常用方法是使用NSTimerdispatch_after Set one of those up, and when the timer fires, do whatever you need to do. 设置其中一个,当计时器触发时,做你需要做的任何事情。 Meanwhile, use an infinite timeout on the actual readData call. 同时,在实际的readData调用上使用无限超时。 Note that infinite timeouts aren't actually infinite. 请注意,无限超时实际上并不是无限的。 The OS will still time out after, say, 10 minutes without successfully reading. 在没有成功阅读的情况下,操作系统仍会在10分钟后超时。 If you really want to keep the connection alive forever, you might be able to set a socket option. 如果您确实希望永久保持连接,则可以设置套接字选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM