NSPOSIXErrorDomain Code=12“无法分配内存”在3G网络中

发布于 2024-11-08 20:12:06 字数 2312 浏览 0 评论 0原文

我正在尝试在 iPhone 应用程序中发送 FTP 服务器上的文件。 在 WiFi 和 GSM:EDGE 网络中似乎一切正常,但在 3G 网络中出现错误(并非总是如此,但经常出现):

错误域=NSPOSIXErrorDomain Code=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: 我不敢相信,但这是真的: SimpleFTPSample 来自苹果也受到该问题的影响。

I'm trying to send a file on FTP server in my iPhone application.
Everything seems to be okay in WiFi and GSM:EDGE network, but in 3G network an error appears (not always, but very often):

Error Domain=NSPOSIXErrorDomain
Code=12 "The operation couldn’t be
completed. Cannot allocate memory"

Below the code where the error appears:

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

What can be important, the whole sending is done in separate thread which has it's own NSAutoreleasePool.
Is there anyone who got the issue? Any suggestion? I would be appreciate.

UPDATE:
I've just checked that popular iPhone application "FTP On The Go" has got the same (?) issue during sending a file in 3G network! There is no error handled, but the transfer stops.

UPDATE 2:
I can't believe it, but it's true: SimpleFTPSample from Apple is also affected with the issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

触ぅ动初心 2024-11-15 20:12:06

这就是 - 解决方案(或者更确切地说是解决方法):

您应该将 writeStream 的属性设置为 false,以关闭默认的持久连接

CFWriteStreamSetProperty( (CFWriteStreamRef)writeStreamRef, kCFStreamPropertyFTPAttemptPersistentConnection, kCFBooleanFalse ) ;

And here it is - the solution (or rather workaround):

you should set property of writeStream to false, to switch off default persistant connection

CFWriteStreamSetProperty( (CFWriteStreamRef)writeStreamRef, kCFStreamPropertyFTPAttemptPersistentConnection, kCFBooleanFalse ) ;
你是暖光i 2024-11-15 20:12:06

已通过使用请求操作 (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;

}

Have resolved this error with using operation for request (NSMutableUrlConnection) with @autorelease{} for main function

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文