3

我想通过 ftp 将图像上传到服务器。

我在苹果文档中找到了一个SimpleFTPSample,并下载了它。

运行应用程序时(我使用的是 xcode 4.5.2,目标为 iphone 5.0 模拟器)它工作正常。我正在尝试通过此应用程序在我的服务器中创建目录并成功。

但是,上传应用程序中提供的图像时会导致“打开流错误”。我没有对应用程序进行任何更改。只需输入网址、用户名和密码。我认为这没有问题,因为我指定的目录已成功创建。

创建目录时,url 是“ftp://54.xyz/newfolder/”,它创建成功。

但是,上传的网址是“ftp://54.xyz/TestImage1.png”

文件路径是“/var/folders/pn/8p0jc4qn70v37j58c1kwf8l80000gn/T/TestImage1.png”

url 是通过将最后一个组件字符串附加到我指定的 ftp url 来获得的。

那么,其中的错误是什么?

在 fn 中,

 - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
 { 



case NSStreamEventErrorOccurred: {
        [self stopSendWithStatus:@"Stream open error"];
    } break;

被调用并显示 Stream open 错误。

我用谷歌搜索了一整天,没有需要的结果。它非常紧迫,我什至无法为此开始赏金。请帮忙

4

3 回答 3

2

在 PutController.m StartSend 中设置 networkStream 委托之前添加这一行为我解决了这个问题:

[self.networkStream setProperty:(id)kCFBooleanFalse forKey:(id)kCFStreamPropertyFTPUsePassiveMode];

如果没有上面的行(或将属性设置为 kCFBooleanTrue 而不是 kCFBooleanFalse),我一直得到 Stream Open Error。我只尝试了一台 FTP 服务器,但它似乎不支持被动模式,这显然是默认的。

于 2013-04-03T20:42:58.630 回答
2

尝试这个....

     - (void)sendDidStart
{
    // self.statusLabel.text = @"Sending";
    [[NetworkManager sharedInstance] didStartNetworkOperation];

}

- (void)updateStatus:(NSString *)statusString
{
    assert(statusString != nil);
    //self.statusLabel.text = statusString;
}

- (void)sendDidStopWithStatus:(NSString *)statusString
{
    if (statusString == nil) {
        statusString = @"Put succeeded";
    }
    [[NetworkManager sharedInstance] didStopNetworkOperation];
}

#pragma mark * Core transfer code

// This is the code that actually does the networking.

// Because buffer is declared as an array, you have to use a custom getter.  
// A synthesised getter doesn't compile.

- (uint8_t *)buffer
{
    return self->_buffer;
}

- (BOOL)isSending
{
    return (self.networkStream != nil);
}

- (void)startSend:(NSString *)filePath
{
    BOOL                    success;
    NSURL *                 url;
    NSLog(@"localFilePathforImage..:%@",localFilePathforImage);
    assert(localFilePathforImage != nil);
    assert([[NSFileManager defaultManager] fileExistsAtPath:localFilePathforImage]);
    assert( [localFilePathforImage.pathExtension isEqual:@"png"] || [localFilePathforImage.pathExtension isEqual:@"jpg"] );

    assert(self.networkStream == nil);      // don't tap send twice in a row!
    assert(self.fileStream == nil);         // ditto

    // First get and check the URL.

    url = [[NetworkManager sharedInstance] smartURLForString:@"ftp://80.544/"];
    success = (url != nil);

    if (success) {
        // Add the last part of the file name to the end of the URL to form the final 
        // URL that we're going to put to.

        url = CFBridgingRelease(
                                CFURLCreateCopyAppendingPathComponent(NULL, ( CFURLRef) url, ( CFStringRef) imageString , false)
                                );
        success = (url != nil);
    }

    // If the URL is bogus, let the user know.  Otherwise kick off the connection.

    if ( ! success) {
        // self.statusLabel.text = @"Invalid URL";
    }    
    else 
    {

        // Open a stream for the file we're going to send.  We do not open this stream; 
        // NSURLConnection will do it for us.

        self.fileStream = [NSInputStream inputStreamWithFileAtPath:localFilePathforImage];
        assert(self.fileStream != nil);

        [self.fileStream open];

        // Open a CFFTPStream for the URL.

        self.networkStream = CFBridgingRelease(
                                               CFWriteStreamCreateWithFTPURL(NULL, ( CFURLRef) url)
                                               );
        assert(self.networkStream != nil);

        // if ([self.usernameText.text length] != 0) {
        success = [self.networkStream setProperty:@"yourusername" forKey:(id)kCFStreamPropertyFTPUserName];
        assert(success);
        success = [self.networkStream setProperty:@"password" forKey:(id)kCFStreamPropertyFTPPassword];
        assert(success);
        //}

        self.networkStream.delegate = self;
        [self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.networkStream open];

        // Tell the UI we're sending.

        [self sendDidStart];
    }
}

- (void)stopSendWithStatus:(NSString *)statusString
{
    if (self.networkStream != nil) {
        [self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.networkStream.delegate = nil;
        [self.networkStream close];
        self.networkStream = nil;
    }
    if (self.fileStream != nil) {
        [self.fileStream close];
        self.fileStream = nil;
    }
    [self sendDidStopWithStatus:statusString];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our 
// network stream.
{
#pragma unused(aStream)
    assert(aStream == self.networkStream);

    switch (eventCode) {
        case NSStreamEventOpenCompleted: {
            [self updateStatus:@"Opened connection"];
        } break;
        case NSStreamEventHasBytesAvailable: {
            assert(NO);     // should never happen for the output stream
        } break;
        case NSStreamEventHasSpaceAvailable: {
            [self updateStatus:@"Sending"];

            // If we don't have any data buffered, go read the next chunk of data.

            if (self.bufferOffset == self.bufferLimit) {
                NSInteger   bytesRead;

                bytesRead = [self.fileStream read:self.buffer maxLength:sSendBufferSize];

                if (bytesRead == -1) {
                    [self stopSendWithStatus:@"File read error"];
                } else if (bytesRead == 0) {
                    [self stopSendWithStatus:nil];
                } else {
                    self.bufferOffset = 0;
                    self.bufferLimit  = bytesRead;
                }
            }

            // If we're not out of data completely, send the next chunk.

            if (self.bufferOffset != self.bufferLimit) {
                NSInteger   bytesWritten;
                bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
                assert(bytesWritten != 0);
                if (bytesWritten == -1) {
                    [self stopSendWithStatus:@"Network write error"];
                } else {
                    self.bufferOffset += bytesWritten;
                }
            }
        } break;
        case NSStreamEventErrorOccurred: {
            [self stopSendWithStatus:@"Stream open error"];
        } break;
        case NSStreamEventEndEncountered: {
            // ignore
        } break;
        default: {
            assert(NO);
        } break;

    }
}
于 2013-01-22T14:12:21.027 回答
1

我有同样的问题。

这是每个托管服务提供商。我认为问题在于代码可能会被登录名中的“@”符号混淆= dev@atoz.com。?

您是否在 @sing 中使用用户名?

于 2013-02-14T12:18:31.620 回答