2013-04-05 34 views
12

我已下載WiTap代碼來自Apple的網站。它用於通過本地WiFi網絡傳輸數據。我正在一個項目中作爲客戶端 - 服務器體系結構進行交互。我從客戶端發送NSData到服務器。如何在iOS中通過WiFi傳輸大文件

我做了2個項目;一個用於客戶端和一個服務器

在客戶端側項目,我提出以下更改 對於我通過添加下面的方法改性的AppController.m文件

AppController.m(客戶端側)

- (void)sendData:(NSData*)pobjData 
{ 
    assert(self.streamOpenCount == 2); 

    if ([self.outputStream hasSpaceAvailable]) 
    { 
     NSInteger bytesWritten; 

     NSUInteger length = [pobjData length]; 

     bytesWritten = [self.outputStream write:[pobjData bytes] maxLength:[pobjData length]]; 

     NSLog(@"written bytes -> %d",bytesWritten); 
    } 
} 

然後通過調用這個方法我發送數據。

在服務器側項目,我提出以下爲chagnes我通過修改以下方法

AppController.m(服務器側)

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode 
{ 
    #pragma unused(stream) 

    switch(eventCode) { 

     case NSStreamEventOpenCompleted: { 
      self.streamOpenCount += 1; 
      assert(self.streamOpenCount <= 2); 

      // Once both streams are open we hide the picker and the game is on. 

      if (self.streamOpenCount == 2) { 
       [self dismissPicker]; 

       [self.server deregister]; 
      } 
     } break; 

     case NSStreamEventHasSpaceAvailable: { 
      assert(stream == self.outputStream); 
      // do nothing 
     } break; 

     case NSStreamEventHasBytesAvailable: 
     { 
      if (stream == self.inputStream) 
      { 

       NSInteger bytesRead; 
       uint32_t buffer[32768]; 

       NSMutableData *_data = [NSMutableData data]; 

       // Pull some data off the network. 
       bytesRead = [self.inputStream read:buffer maxLength:sizeof(buffer)]; 
       if (bytesRead == -1) { 

       } else if (bytesRead == 0) { 

       } else { 
        // FIXME: Popup an alert 

        const long long expectedContentLength = bytesRead; 
        NSUInteger expectedSize = 0; 

        // expectedContentLength can be represented as NSUInteger, so cast it: 
        expectedSize = (NSUInteger)expectedContentLength; 

        [_data appendBytes:buffer length:expectedSize]; 

        NSLog(@"\"Data received has length: %d", _data.length); 

        [self performSelector:@selector(getData:) withObject:_data afterDelay:1.0]; 
       } 
      } 
     } 
      break; 

     default: 
      assert(NO); 
      // fall through 
     case NSStreamEventErrorOccurred: 
      // fall through 
     case NSStreamEventEndEncountered: { 
      [self setupForNewGame]; 
     } break; 
    } 
} 

修改AppController.m文件並添加的方法將接收到的數據寫入文件

 #define kUserDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) 

-(void)getData:(NSMutableData *)pData 
{ 
       NSFileManager *tmpmanager = [NSFileManager defaultManager]; 
       [tmpmanager createFileAtPath:[AppController getDocumentDirectoryPath:[NSString stringWithFormat:@"%@.png",[NSDate date]]] contents:pData attributes:nil]; 
} 


+(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName 
{ 
      NSString *strPath=nil; 

      if(pStrPathName) 
       strPath = [[kUserDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName]; 

      return strPath; 
} 

我將.png文件轉換爲NSData並將它們從cl客戶端到服務器端。服務器將文件下載到文檔目錄

問題是,當我從客戶端傳輸文件時,它會在文檔目錄下載到服務器端。一切工作正常的情況下,小文件。如果文件大小超過8kB,則在文檔目錄下寫入的文件會被損壞。

請幫助我發送大文件。

回答

0

可以使用AsyncSocket可以從

https://github.com/roustem/AsyncSocket被下載,

這是客觀-C包裝建立在CFSocket和CFNetwork的,它能夠處理大量的與TCP/UDP協議上的數據傳送的本地WiFi。

您可以在這裏找到https://github.com/darkseed/cocoaasyncsocket/wiki/iPhone

類維基是非常簡單和容易implement.Give試試看

+0

我試了一下,但在那種情況下,我也面臨同樣的問題。我曾經通過UDP傳輸,還有我無法發送大於9 kB的文件。 – HarshIT 2013-04-05 09:35:51

+0

https://github.com/robbiehanson/CocoaAsyncSocket是CocoaAsyncSocket的官方GitHub回購。 – zadr 2013-04-05 09:37:17

+0

@zadr是老兄,我使用了相同的代碼。 ..... – HarshIT 2013-04-05 09:37:41

1

的問題是,您的代碼不會循環來收集所有可用數據直到結束(或者循環發送所有數據)。所以你只能收到第一個數據緩衝區。如果圖像很小,那麼工作正常,如果圖像較大,則永遠不會。

您需要編寫代碼,以便在存在緩衝區空間時繼續發送,直到發送完所有數據並保持讀取數據(到達NSMutableData實例變量,而不是本地變量),直到到達流的末尾。

-1

您已經從您需要放置系統的IP地址的網絡服務,您要發送文件的位置,然後當您可以連接輸入的IP地址時,您可以使用Base64和NSData發送文件格式。

+0

請參閱WiTap代碼,它使用Bonjour服務。 – HarshIT 2013-04-25 07:25:23

+0

我需要將該web服務放在哪裏:D,請閱讀完整的問題。 – HarshIT 2013-04-25 07:28:40