如何在iOS中通过wifi传输大文件

我从Apple的网站上下载了WiTap Code。 它用于通过本地wifi网络传输数据。 我正在一个项目中作为客户端 – 服务器架构进行交互。 我正在从客户端向服务器发送NSData。

我做了两个项目; 一个用于客户端,一个用于服务器

在客户端项目,我做了以下更改为此我通过添加以下方法修改了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文件

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

并添加了一种将接收到的数据写为文件的方法

  #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并将它们从客户端发送到服务器端。 服务器将文件下载到文档目录

问题是,当我从客户端传输文件时,它会被下载到文档目录的服务器端。 在文件很小的情况下,一切正常。 如果文件大小超过8kB,则在文档目录中写入的文件会损坏。

请帮助我能够发送大文件。

问题是您的代码不会循环收集所有可用数据直到结束(或循环发送所有数据)。 所以你只收到第一个数据缓冲区。 如果图像很小则可以正常工作,如果图像较大则永远不会。

您需要编写代码,以便在存在缓冲区空间时继续发送,直到发送所有数据并继续读取数据(到NSMutableData实例变量,而不是局部变量),直到到达流的末尾。

您可以使用可从中下载的AsyncSocket

https://github.com/roustem/AsyncSocket

这是一个基于CFSocket和CFNetwork的Objective-c包装器,它可以在本地wifi上使用TCP / UDP协议处理大量数据传输。

你可以在这里找到wiki https://github.com/darkseed/cocoaasyncsocket/wiki/iPhone

该课程非常简单,易于实现。试一试

您已经建立了一个Web服务,您需要将系统的IP地址,您要发送文件的位置放在哪里,之后当您可以使用输入的IP地址连接时,您可以发送Base64和NSData格式的文件。