2012-07-06 97 views
0

我正在用ftp協議下載文件。現在,爲了檢查處理錯誤的能力,我模擬了一些網絡錯誤的發生。處理網絡InputStream中的代碼如下:如何處理ftp下載請求塊

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

如果我手動關閉無線網絡連接或關閉我的無線路由器(網絡連接標誌是關閉的),一個「NSStreamEventErrorOccurred」將返回和下載過程將被正確終止。但是,如果我關閉調制解調器,同時保持無線路由器打開(網絡連接標誌打開)。下載過程停留在「NSStreamEventHasBytesAvailable」情況。即使打開互聯網連接後,它仍然卡住。

我想知道它爲什麼卡住了,我該如何檢測這種錯誤。我該如何處理這種情況?

回答

1

首先,考慮到這一點和運行測試的榮譽。許多開發人員認爲「網絡連接將始終有效」。

其次,您使用NSStream進行FTP下載似乎有點奇怪,你知道NSURLConnection支持FTP,對吧?除非你真的很奇怪,否則你應該使用內置的URL loading facilities

在任何情況下,這裏的問題是沒有辦法讓應用程序(或計算機)確定連接是否因爲連接失敗(應該重新啓動或取消)或因爲連接暫停它只是運行緩慢(在這種情況下需要耐心)。

我有點驚訝,當您的調制解調器重新連接時,不會恢復活動的TCP會話;這表明,當調制解調器鏈路斷開或您的IP在重新連接時發生變化時,您ISP的路由器可能會斷開連接,但這對您的問題無關緊要。

一段時間不活動後,TCP會話通常最終會被操作系統(或上游路由器)超時,但這可能會持續很長的時間。所以你可能需要做的是實現一個超時。

我可能會做的事情(假設你像上面討論的那樣繼續使用NSStream)有一個NSTimer週期性地發射 - 也許每15秒鐘一次 - 並且回調比較當前時間和你設置的時間戳每個NSStreamEventHasBytesAvailable事件。如果時間戳太舊(比如超過15秒),請根據需要取消或重新啓動下載並通知用戶。

但是,再次看看只使用NSURLConnection

+0

我只是使用來自App Develop Library的使用NSStream的SimpleFTP。 NSURLConnection比NSStream更好嗎? – itenyh 2012-07-06 03:14:35

+0

@itenyh「更好」取決於你正在嘗試做什麼。一般規則是儘可能使用最高級別的API,並且NSURLConnection比NSStream高得多。我不明白爲什麼FTP需要NSStream。 – 2012-07-06 16:36:03