FTP

FTPコマンド

コマンド 説明
ls ファイル一覧を取得する
pwd カレントディレクトリを取得する
cd dir ディレクトリを移動する
mkdir ディレクトリを作成する
delete file ファイルを削除する
get ファイルをダウンロードする
mget 複数のファイルをダウンロードする
put ファイルをアップロードする
mput 複数のファイルをアップロードする
passive PASVモードに変更する
ascii アスキー転送に変更する
binary バイナリ転送に変更する
bye, quit, exit 切断する

FTP応答コード

応答コード 意味
110 RESTコマンドのためのマーカー応答である。
120 サービスは停止しているが、nnn分後に準備できる。
125 データコネクションはすでに確立されている。このコネクションで転送を開始する。
150 ファイルステータスは正常である。データコネクションを確立する。
200 コマンドは正常に受け入れられた。
202 コマンドは実装されていない。SITEコマンドでOSコマンドが適切でない場合など。
211 STATコマンドに対するレスポンス。
212 STATコマンドによるディレクトリ情報を示す。
213 STATコマンドによるファイル情報を示す。
214 HELPコマンドに対するレスポンス。
215 SYSTコマンドに対するレスポンス。
220 新規ユーザー向けに準備が整った。ログイン時に表示される場合を想定している。
221 コントロールコネクションを切断する。QUITコマンド時のレスポンス。
225 データコネクションを確立した。データの転送は行われていない。
226 要求されたリクエストは成功した。データコネクションをクローズする。
227 PASVコマンドへのレスポンス。h1~h4はIPアドレス、p1~p2はポート番号を示す。
230 ユーザーログインの成功。
250 要求されたコマンドによる操作は正常終了した。
257 ファイルやディレクトリを作成したというのがRFCでの意味だが、MKDコマンドの結果以外に、実際にはPWDコマンドの結果にも用いられる。
331 パスワードの入力を求める。
332 ACCTコマンドで課金情報を指定する必要がある。
350 他の何かしらの情報を求めている。
421 サービスを提供できない。コントロールコネクションを終了する。サーバのシャットダウン時など。
425 データコネクションをオープンできない。
426 何かしらの原因により、コネクションをクローズし、データ転送も中止した。
450 要求されたリクエストはアクセス権限やファイルシステムの理由で実行できない。
451 ローカルエラーのため処理を中止した。
452 ディスク容量の問題で実行できない。
500 コマンドの文法エラー。
501 引数やパラメータの文法エラー。
502 コマンドは未実装である。
503 コマンドを用いる順番が間違っている。
504 引数やパラメータが未実装。
530 ユーザーはログインできなかった。
532 ファイル送信には、ACCTコマンドで課金情報を確認しなくてはならない。
550 要求されたリクエストはアクセス制限やファイルシステムの理由で実行できない。
551 ページ構造のタイプの問題で実行できない。
552 ディスク容量の問題で実行できない。
553 ファイル名が間違っているため実行できない。

ファイルダウンロード

ファイルダウンロードは次の手順で行います。

 

  1. InternetOpen() でWinInetを初期化、インターネットハンドルを取得する
  2. InternetConnect() でFTP接続
  3. FtpSetCurrentDirectory() でカレントディレクトリ移動
  4. FtpGetFile() でファイルダウンロード
  5. InternetCloseHandle() でインターネットハンドルを閉じる

WinInet初期化

WinInetを使うための前準備として「wininet.h」をインクルードし、「wininet.lib」をリンクしておきます。

 

WinInetライブラリの関数を使用する前にまず、InternetOpen() を使ってWinInet自体の初期化を行います。

HINTERNET InternetOpen(
	IN LPCTSTR lpszAgent,
	IN DWORD dwAccessType,
	IN LPCTSTR lpszProxyName,
	IN LPCTSTR lpszProxyBypass,
	IN DWORD dwFlags
);
説明 WinInetを初期化する。
引数
lpszAgent:
アプリケーションの名前を指定する。
dwAccessType:
アクセスタイプを指定する。
lpszProxyName:
プロキシサーバの名前を指定する。
lpszProxyBypass:
ホスト名またはIPアドレスを指定する。
dwFlags:
関数処理のオプションを指定する。
戻り値 成功した場合はインターネットハンドルを返す。失敗時はNULLを返す。

FTP接続

InternetConnect() でFTPサーバに接続します。

HINTERNET InternetConnect(
	IN HINTERNET hInternet,
	IN LPCTSTR lpszServerName,
	IN INTERNET_PORT nServerPort,
	IN LPCTSTR lpszUsername,
	IN LPCTSTR lpszPassword,
	IN DWORD dwService,
	IN DWORD dwFlags,
	IN DWORD dwContext
);
説明 FTPサーバに接続する。
引数
hInternet:
InternetOpen() で取得したハンドルを指定する。
lpszServerName:
ホスト名もしくはIPアドレスを指定する。
nServerPort:
TCP/IPポート番号、もしくは次のいずれかの定義値を指定する。
INTERNET_DEFAULT_FTP_PORT FTPサーバのデフォルトポート
INTERNET_DEFAULT_GOPHER_PORT ゴーファーサーバーのデフォルトポート(70)
INTERNET_DEFAULT_HTTP_PORT HTTPサーバーのデフォルトポート(80)
INTERNET_DEFAULT_HTTPS_PORT HTTPSサーバーのデフォルトポート(443)
INTERNET_DEFAULT_SOCKS_PORT SOCKSファイアーウォールサーバーのデフォルト ポート(1080)
INTERNET_INVALID_PORT_NUMBER dwServiceで特定されるサービスのデフォルトポート
lpszUsername:
ユーザー名を指定する。
lpszPassword:
パスワードを指定する。
dwService:
サービスのタイプを指定する。
dwFlags:
使用されるサービスに特異的なフラグを指定する。
dwContext:
コールバックのリターンハンドルのためのアプリケーションコンテキストを識別するために使用される、アプリケーション定義値を指定する。
戻り値 成功した場合はインターネットハンドルを返す。失敗時はNULLを返す。

カレントディレクトリ指定

FtpSetCurrentDirectory() でカレントディレクトリの指定を行います。

BOOL FtpSetCurrentDirectory(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszDirectory
);
説明 FTPサーバのカレントディレクトリを指定する。
引数
hFtpSession:
InternetConnect() で取得したハンドルを指定する。
lpszDirectory:
ディレクトリ名を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

ファイルのダウンロード

FtpGetFile() でファイルのダウンロードを行います。

BOOL FtpGetFile(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszRemoteFile,
	IN LPCSTR lpszNewFile,
	IN BOOL fFailIfExists,
	IN DWORD dwLocalFlagsAndAttributes,
	IN DWORD dwInternetFlags,
	IN DWORD dwContext
);
説明 FTPサーバからファイルを取得する。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszRemoteFile:
取得対象とするファイルの名前を指定する。
lpszNewFile:
取得したファイルの保存ファイル名を指定する。
fFailIfExists:
ローカルにlpszNewFileで指定したファイルが存在する場合の挙動を指定する。TRUEを指定した場合、ファイルが存在するときにこの関数は失敗する。
dwLocalFlagsAndAttributes:
新しいファイルの性質を指定する。通常はFILE_ATTRIBUTE_NORMALを指定する。
dwInternetFlags:
ダウンロードするときに関数がどのようにファイルを取り扱うかを指定する。
FTP_TRANSFER_TYPE_ASCII アスキーファイルを転送する。
FTP_TRANSFER_TYPE_BINARY バイナリファイルを転送する。ファイルは変化することなく正確に転送される。
FTP_TRANSFER_TYPE_UNKNOWN デフォルト(バイナリ)で転送する。
INTERNET_FLAG_TRANSFER_ASCII アスキーファイルとして転送する。
INTERNET_FLAG_TRANSFER_BINARY バイナリファイルとして転送する。
dwContext:
アプリケーション定義の値を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

FTP切断

InternetCloseHandle() でインターネットから切断します。この関数は次のように定義されています。

BOOL InternetCloseHandle(
	IN HINTERNET hInet
);
説明 インターネットハンドルをクローズする。
引数
hInet:
インターネットハンドルを指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

FTP処理を行うにあたって「InternetOpen() でオープンしたWinInet用のインターネットハンドル」と「InternetConnect() でオープンしたFTP用のインターネットハンドル」の2つをオープンしていますので、両方ともクローズする必要があります。 FTP側をクローズしてからWinInet側をクローズします。

実装例

実装例を以下に示します。まず、接続処理です。

BOOL FtpConnect(
	LPCTSTR	serverName,	// [i]	サーバ名
	LPCTSTR	userName,	// [i]	ユーザー名
	LPCTSTR	password,	// [i]	パスワード
	LPCTSTR	baseDir )	// [i] カレントディレクトリ
{
	BOOL		bRet = FALSE;
	HINTERNET	hInternet = NULL;
	HINTERNET	hFtp = NULL;



	//==== インターネットオープン ====//
	hInternet = InternetOpen(_T("Hoge"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
	if(hInternet == NULL)
	{
		//-==- 失敗 -==-//
		return FALSE;
	}


	//==== FTP接続 ====//
	hFtp = InternetConnect(hInternet, serverName, INTERNET_INVALID_PORT_NUMBER, userName, password, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
	if(hFtp == NULL)
	{
		//-==- 失敗 -==-//
		return FALSE;
	}


	//==== カレントディレクトリ設定 ====//
	bRet = FtpSetCurrentDirectory(hFtp, baseDir);
	if(bRet == FALSE)
	{
		//-==- 失敗 -==-//
		return FALSE;
	}


	return TRUE;
}

次にダウンロード処理です。

BOOL FtpDownload(
	HINTERNET	hFtp,		// [i]	FTPハンドル
	LPCTSTR		remoteFile,	// [i]	ダウンロード対象ファイル名
	LPCTSTR		localFile )	// [i]	ダウンロードしたファイルの保存ファイル名
{
	BOOL	bRet = FALSE;



	bRet = FtpGetFile(hFtp, remoteFile, localFile, TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0);
	if(bRet == FALSE)
	{
		//-==- 失敗 -==-//
	}


	return bRet;
}

ファイルアップロード

基本的な流れはファイルダウンロードと変わりません。ファイルダウンロードしていた部分を以下の処理に置き換えることでアップロード処理を実装することが出来ます。

ファイルのアップロード

FtpPutFile() でファイルのアップロードを行う。

BOOL FtpPutFile(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszLocalFile,
	IN LPCSTR lpszNewRemoteFile,
	IN DWORD dwFlags,
	IN DWORD dwContext
);
説明 FTPサーバにファイルをアップロードする。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszLocalFile:
アップデート対象とするファイルの名前を指定する。
lpszNewRemoteFile:
サーバに保存するファイル名を指定する。
dwFlags:
FtpGetFile() の同名パラメータの説明を参照のこと。
dwContext:
アプリケーション定義の値を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

ディレクトリ作成

サーバに新規ディレクトリを作成するには FtpCreateDirectory() を使用する。

BOOL FtpCreateDirectory(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszDirectory
);
説明 FTPサーバに新規ディレクトリを作成する。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszDirectory:
作成するディレクトリの名前を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

ファイル削除

サーバのファイル削除するには FtpDeleteFile() を使用します。

BOOL FtpDeleteFile(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszFileName
);
説明 FTPサーバに新規ディレクトリを作成する。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszFileName:
削除対象ファイルの名前を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

ファイル一覧取得

カレントディレクトリにあるファイル・ディレクトリを取得する方法を紹介します。

 

まず、カレントディレクトリを取得するために FtpGetCurrentDirectory() を使います。

BOOL FtpGetCurrentDirectory(
	IN HINTERNET hFtpSession,
	OUT LPSTR lpszCurrentDirectory,
	IN OUT LPDWORD lpdwCurrentDirectory
);
説明 カレントディレクトリを取得する。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszCurrentDirectory:
カレントディレクトリ名を格納するバッファを指定する。
lpdwCurrentDirectory:
バッファサイズを格納している変数のアドレスを指定する。関数が成功した際は、バッファにコピーした文字数を受け取る。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。

次にカレントディレクトリ内のディレクトリおよびファイルを検索します。検索には FtpFindFirstFile() および InternetFindNextFile() を使用します。

HINTERNET FtpFindFirstFile(
	IN HINTERNET hFtpSession,
	IN LPCSTR lpszSearchFile,
	OUT LPWIN32_FIND_DATA lpFindFileData,
	IN DWORD dwFlags,
	IN DWORD dwContext
);
説明 指定ディレクトリの中を検索する。
引数
hFtpSession:
FTPセッションのハンドルを指定する。
lpszSearchFile:
検索対象とするディレクトリおよびファイルの名前を指定する。ワイルドカード指定も可。NULLもしくは空文字列を指定した場合は、カレントディレクトリの最初のファイルを見つける。
lpFindFileData:
見つけたディレクトリおよびファイルの情報を格納するWIN32_FIND_DATA構造体を指定する。
dwFlags:
次のいずれかの値を指定する。
INTERNET_FLAG_DONT_CACHE 戻ってきたものをキャッシュに加えない。
INTERNET_FLAG_HYPERLINK ネットワークからのアイテムをリロードするかどうかを決定する際、サーバーから「期限切れ」だとか最終更新時間がなければ強制的にリロードする。
INTERNET_FLAG_MAKE_PERSISTENT サポートされていない。
INTERNET_FLAG_MUST_CACHE_REQUEST ファイルがキャッシュできないときは一時ファイルを作る。
INTERNET_FLAG_NEED_FILE 同上。
INTERNET_FLAG_NO_CACHE_WRITE 返ってきたものをキャッシュに加えない。
INTERNET_FLAG_RELOAD 要求されたファイル、オブジェクト、ディレクトリのダウンロードをキャッシュからではなく、サーバーからダウンロードすることを強制する。
INTERNET_FLAG_RESYNCHRONIZE FTPリソースはサーバからリロードされる。
dwContext:
アプリケーション定義の値を指定する。
戻り値 検索ハンドルを返す。
BOOL InternetFindNextFile(
	IN HINTERNET hFind,
	OUT LPVOID lpvFindData
);
説明 FtpFindFirstFile() または GopherFindFirstFile() で開始されたファイル検索を続行し、次のファイルを取得する。
引数
hFind:
FtpFindFirstFile() または GopherFindFirstFile() で返された検索ハンドルを指定する。
lpvFindData:
検索結果を格納する構造体を指定する。FTPの場合WIN32_FIND_DATA構造体、Gopherの場合はGOPHER_FIND_DATA構造体を指定する。
戻り値 成功した場合はTRUE、失敗した場合はFALSEを返す。