如何处理ftp下载请求块

时间:2012-07-06 01:33:15

标签: iphone objective-c ftp

我正在使用ftp协议下载文件。现在,为了检查处理错误的能力,我模拟了一些网络错误的发生。处理网络inputStream的代码如下:

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our 
// network stream.
{
#pragma unused(aStream)
    assert(aStream == self.networkStream);
    switch (eventCode) {
    case NSStreamEventOpenCompleted: {
       self.connected = YES; 
    } break;
    case NSStreamEventHasBytesAvailable: {
        NSInteger       bytesRead;
        uint8_t         buffer[32768];

        // Pull some data off the network.
        bytesRead = [self.networkStream read:buffer maxLength:sizeof(buffer)];
         DLog(@"%@,byteRead:%d",self.urlInput,bytesRead);   
        if (bytesRead == -1) {
            [self _stopReceiveWithStatus:@"Network read error"];
        } else if (bytesRead == 0) {
            [self _stopReceiveWithStatus:@"success"];
        } else {
            NSInteger   bytesWritten;
            NSInteger   bytesWrittenSoFar;

            bytesWrittenSoFar = 0;
            do {
                bytesWritten = [self.fileStream write:&buffer[bytesWrittenSoFar] maxLength:bytesRead - bytesWrittenSoFar];
                DLog(@"%@,bytesWritten:%d",self.urlInput,bytesWritten);
                assert(bytesWritten != 0);
                if (bytesWritten == -1) {
                    [self _stopReceiveWithStatus:@"File write error"];
                    break;
                } else {
                    bytesWrittenSoFar += bytesWritten;
                }
            } while (bytesWrittenSoFar != bytesRead);
        }
    } break;
    case NSStreamEventHasSpaceAvailable: {
        assert(NO);     // should never happen for the output stream
    } break;
    case NSStreamEventErrorOccurred: {
        [self _stopReceiveWithStatus:@"Stream open error"];
    } break;
    case NSStreamEventEndEncountered: {
      assert(NO);
    } break;
    default: {
        assert(NO);
    } break;
}
}

如果我手动关闭wifi或关闭无线路由器(网络连接标志关闭),将返回“NSStreamEventErrorOccurred”,下载过程将正确终止。但是,如果我关闭调制解调器,同时保持无线路由器打开(网络连接标志打开)。下载过程停留在“NSStreamEventHasBytesAvailable”的情况下。即使在我打开互联网连接后,它仍然卡住了。

我想知道它为什么会被卡住,我怎么能检测到这种错误。我该如何处理这种情况?

1 个答案:

答案 0 :(得分:1)

首先,感谢您考虑这个并运行测试。许多开发人员认为“网络连接将始终有效。”

其次,使用NSStream进行FTP下载似乎有点奇怪;你知道NSURLConnection支持FTP,对吧?除非你做的事情很奇怪,否则你应该使用内置的URL loading facilities

在任何情况下,这里的问题是,in principle无法让应用程序(或计算机)确定连接是否有暂停,因为连接失败(应该重新启动或取消)或者因为它只是运行缓慢(在这种情况下需要耐心)。

当你的调制解调器重新连接时,我没有恢复活动的TCP会话,这有点让我感到惊讶。这表明,当调制解调器链路断开或者你的IP在重新连接时正在改变时,你的ISP的路由器可能正在断开连接,但这对你的问题来说并不重要。

TCP会话通常最终会在一段时间不活动后由操作系统(或上游路由器)超时,但这可能是一个不可接受的长时间。所以你可能需要做的是实现超时。

我可能会做的事情(假设你按照上面讨论的那样坚持NSStream)会定期NSTimer开火 - 可能每15秒一次 - 然后让回调比较当前时间到您在每个NSStreamEventHasBytesAvailable事件上设置的时间戳。如果时间戳太旧(例如,超过15秒),请根据需要取消或重新启动下载并通知用户。

但是,请再看一下,使用NSURLConnection