3

ftp経由でサーバーに画像をアップロードしたい。

AppleのドキュメントでSimpleFTPSampleを見つけて、ダウンロードしました。

アプリを実行すると(xcode 4.5.2、ターゲットiphone 5.0シミュレーターを使用しています)、正常に動作します。このアプリを使用してサーバーにディレクトリを作成しようとしていますが、成功しました。

ただし、アプリで提供されている画像をアップロードすると、「オープンストリームエラー」が発生します。アプリに変更はありませんでした。URL、ユーザー名、パスワードを入力するだけです。指定したディレクトリが正常に作成されたので、問題ないと思います。

ディレクトリの作成中、URLは「ftp://54.xyz/newfolder/」で正常に作成されます。

ただし、URLのアップロード中は「ftp://54.xyz/TestImage1.png」です。

ファイルパスは「/var/folders/pn/8p0jc4qn70v37j58c1kwf8l80000gn/T/TestImage1.png」です。

urlは、最後のコンポーネント文字列に、指定したftpurlを追加することで取得されます。

それで、それの間違いは何ですか?

fnでは、

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



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

呼び出され、ストリームオープンエラーが表示されました。

私は一日中グーグルで検索しましたが、必要な結果はありませんでした。その非常に緊急であり、私はこれに対する報奨金を開始することさえできません。助けてください

4

3 に答える 3

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 に答える
2

PutController.m StartSendでnetworkStreamデリゲートを設定する前にこの行を追加すると、問題が修正されました。

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

上記の行がない場合(またはプロパティがkCFBooleanFalseではなくkCFBooleanTrueに設定されている場合)、一貫してStreamOpenErrorが発生します。FTPサーバーを1つだけ試しましたが、明らかにデフォルトであるパッシブモードをサポートしていないようです。

于 2013-04-03T20:42:58.630 に答える
1

同じ問題があります。

これはホスティングプロバイダーごとです。問題は、ログイン名=dev@atoz.comの「@」記号によってコードが混乱する可能性があることだと思います。

@ singでユーザー名を使用していますか?

于 2013-02-14T12:18:31.620 に答える