我正在尝试在我的iPhone应用程序中的FTP服务器上发送文件。 在WiFi和GSM:EDGE网络中,一切似乎都没问题,但在3G网络中出现错误(并非总是如此,但经常出现):
错误域= NSPOSIXErrorDomain 代码= 12“操作不可能 完成。无法分配内存“
出现错误的代码下方:
- (void)stream:(NSStream*)aStream handleEvent:(NSStreamEvent)eventCode {
switch( eventCode ) {
case NSStreamEventHasSpaceAvailable: {
if( _readDataOffset == _readDataLimit ) {
NSInteger readDataLen = [_readStream read:[_readData mutableBytes] maxLength:kReadDataLength];
NSLog(@"readDataLen is %d",readDataLen);
if( -1 == readDataLen ) {
_error = [[_readStream streamError] retain];
_keepRunning = NO;
} else if( 0 == readDataLen ) {
_keepRunning = NO;
} else {
_readDataOffset = 0;
_readDataLimit = readDataLen;
}
}
if( _readDataOffset != _readDataLimit ) {
NSOutputStream* writeStream = (NSOutputStream*)aStream;
uint8_t *buffer = (void *)[_readData bytes];
// vvvv and here the value of writtenDataLen is often -1 (but only on 3G network)
NSInteger writtenDataLen = [writeStream write:&buffer[_readDataOffset] maxLength:_readDataLimit - _readDataOffset];
if( writtenDataLen > 0 ) {
_readDataOffset += writtenDataLen;
_writtenDataLen += writtenDataLen;
[self ftpPutDidWriteInternal];
} else if( -1 == writtenDataLen ) {
_error = [[writeStream streamError] retain];
_keepRunning = NO;
}
}
} break;
case NSStreamEventErrorOccurred: {
_error = [aStream.streamError retain];
_keepRunning = NO;
} break;
}
}
重要的是,整个发送是在具有自己的NSAutoreleasePool的单独线程中完成的。 有没有人得到这个问题?有什么建议吗?我很感激。
更新: 我刚刚检查过流行的iPhone应用程序“FTP On The Go”在3G网络中发送文件时遇到了同样的问题(?)!没有处理错误,但传输停止。
更新2: 我无法相信,但这是真的:来自Apple的SimpleFTPSample也受到了这个问题的影响。
答案 0 :(得分:1)
这就是 - 解决方案(或者更确切地说是解决方法):
你应该将writeStream的属性设置为false,以关闭默认的持久连接
CFWriteStreamSetProperty( (CFWriteStreamRef)writeStreamRef, kCFStreamPropertyFTPAttemptPersistentConnection, kCFBooleanFalse ) ;
答案 1 :(得分:1)
使用NSMutableUrlConnection
主要功能的请求(@autorelease{}
)操作解决了此错误
- (void)main
NSURLConnection* connection;
@autoreleasepool //urgently needed for 3G upload
{
self.currentRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"test.php"]];
[self.currentRequest setHTTPMethod:@"PUT"];
[self.currentRequest setHTTPBody:self.data];//inpustStream doesn't work
connection = [NSURLConnection connectionWithRequest:self.currentRequest delegate:self];
[connection start];
}//end autorelease pool
do
{
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]];
if ([self isCancelled])
{
connection = nil;
isFailed = YES;
break;
}
self.status(statusUpdateMessage);
}
while (!isFailed && !isCompleted);
[timer invalidate];//test
timer = nil;
//corresponding of status via blocks
self.completed(!isFailed);
self.status(isFailed ? errorMessage : @"Completed");
if (isFailed)
{
self.failed(errorMessage != nil ? errorMessage : @"Undefined error");
}
self.data = nil;
self.currentRequest = nil;
connection = nil;
}