我从Apple网站下载了WiTap代码。它用于通过本地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);
}
}
然后通过调用此方法发送数据。
在服务器端项目中,我通过修改以下方法修改了AppController.m文件以下的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;
}
}
并添加了一种将接收到的数据写为文件的方法
#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,则在文档目录中写入的文件将被破坏。
请帮我发送大文件。
答案 0 :(得分:1)
问题是你的代码没有循环来收集所有可用数据直到最后(或循环发送所有数据)。所以你只收到第一个数据缓冲区。如果图像很小则可以正常工作,如果图像较大则永远不会。
您需要编写代码,以便在有缓冲区空间时继续发送,直到发送所有数据并继续读取数据(转换为NSMutableData
实例变量,而不是本地变量),直到流结束到了。
答案 1 :(得分:0)
您可以使用可从
下载的AsyncSockethttps://github.com/roustem/AsyncSocket,
这是一个基于CFSocket和CFNetwork的Objective-c包装器,它可以在本地wifi上使用TCP / UDP协议处理大量数据传输。
您可以在https://github.com/darkseed/cocoaasyncsocket/wiki/iPhone
找到维基该课程非常简单,易于实施。试一试
答案 2 :(得分:-1)
您已经建立了一个Web服务,您需要将系统的IP地址,您要发送文件的位置放在哪里,之后当您可以使用输入的IP地址连接时,您可以发送Base64和NSData格式的文件