読者です 読者をやめる 読者になる 読者になる

Natural Software

KinectなどのDepthセンサーを中心に活動しています

MFC de FTP 通信

C++ MFC

ちょいと FTP クライアントを作成する必要がありそうなので調べてみた。
環境は Visual Studio 2008 SP1

// FtpTest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include "FtpTest.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一のアプリケーション オブジェクトです。

CWinApp theApp;

using namespace std;

// std::tr1::〜を std::〜として使えるようにする
namespace std {
    using namespace std::tr1;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // MFC を初期化して、エラーの場合は結果を印刷します。
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: 必要に応じてエラー コードを変更してください。
        _tprintf(_T("致命的なエラー: MFC の初期化ができませんでした。\n"));
        nRetCode = 1;
    }
    else
    {
        // TODO: アプリケーションの動作を記述するコードをここに挿入してください。
        TRY {
            // FTPサーバへ接続
            // (作成した CFtpConnection クラスは最後に delete する必要がある)
            typedef std::shared_ptr< CFtpConnection > FtpClient;
            CInternetSession net;
            FtpClient ftp = FtpClient( net.GetFtpConnection( "FTP サーバアドレス",
                "ユーザ名", "パスワード", INTERNET_INVALID_PORT_NUMBER,
                TRUE ) ); // <- これを TRUE にしないと動かない

            // ディレクトリを作成
            ftp->CreateDirectory( "test" );

            // 作成したディレクトリに移動
            ftp->SetCurrentDirectory( "test" );

            // FTP 側カレントフォルダの取得
            CString dir;
            ftp->GetCurrentDirectory( dir );
            std::cout << dir << std::endl;

            // アップロード
            ftp->PutFile( "FtpTest.cpp", "FtpTest.cpp", FALSE );

            // ダウンロード
            ftp->GetFile( "FtpTest.cpp", "C:\\FtpTest.cpp", FALSE );

            // ファイル名の変更
            ftp->Rename( "FtpTest.cpp", "Test.cpp" );

            // ファイルの削除
            ftp->Remove( "Test.cpp" );

            // 上のディレクトリに移動して削除
            ftp->SetCurrentDirectory( "../" );
            ftp->RemoveDirectory( "test" );

            // 通信完了
            ftp->Close();

            std::cout << "通信完了" << std::endl;
        }
        CATCH ( CInternetException, ex ) {
            char    errorMessage[256];
            ex->GetErrorMessage( errorMessage, sizeof(errorMessage) );
            std::cout << errorMessage << std::endl;
        }
        END_CATCH
    }

    return nRetCode;
}


思ったよりも全然難しくなく、あっさりと出来てしまった・・・
一行ずつステップしながら一緒に FTP クライアントツールFTP サーバの状態を見てみると動作状況が良く分かる。


ついでに、SP1 でやったので shared_ptr が boost なしで使えるのがウレシイ:)