FTPクライアントのサンプルコード(C#ソースコード):DriveHQのFTPサーバーへの接続多くのユーザーから、自身のソフトウェアプロジェクトでDriveHQのFTPサーバーに接続する方法について問い合わせがありました。そこで今回は、まずFTPに関する一般的な情報を提供し、その後C#のソースコードをご紹介します。
DriveHQ は FTP サーバーホスティングサービスを提供しています。当社は通常の FTP および FTPS プロトコルをサポートしています。当社の FTP サービスの主な利点の 1 つは、当社の幅広いクラウド IT サービスとシームレスに統合されていることです。ユーザーは Web ブラウザを使用して FTP ファイルにアクセスできます。 マップされたドライブ(WebDAV) またはDriveHQ FileManagerクライアントソフトウェアを使用できます。また、当社のWebベースのグループ管理ツールを使用して、FTPユーザー(サブユーザー)を作成および管理することもできます。
通常のFTPプロトコルは暗号化せずにデータを送信するため、安全ではないと考えられています。強力なSSLセキュリティを実現するには、FTPS(SSL/TLS経由のFTP)を使用できます。SSLセキュリティを有効にするには、2つの方法があります:
暗黙: FTPクライアントは、特別なFTPSポート番号(デフォルトは990)に直接接続します。
明示的(FTPES): FTPクライアントは通常のFTPポート番号21に接続し、その後、セキュリティをアップグレードするためにSTARTTLSコマンドを発行します。
DriveHQのFTPサーバーはFTPSとFTPESの両方をサポートしています。ほとんどのFTPクライアントアプリケーションはFTPSとFTPESをサポートしており、例えばFileZilla、CuteFTP、WsFTP、SmartFTP、WinSCP、Fetchなどが挙げられます。
SFTPという別のセキュアファイル転送プロトコルがあり、しばしば「セキュアFTP」と混同されますが、実際には「SSHファイル転送プロトコル」の略で、全く異なるファイル転送プロトコルです。セキュリティの観点から見ると、SSL/TLSとSSHはほぼ同等です。もちろん、SSL/TLSの方がSSHよりも普及しています。DriveHQのFTPサーバーはSFTPをサポートしていません。SFTPに対する強いニーズが見当たらないからです。
アクティブモードおよびパッシブモードのFTP:
FTP接続には、コマンドチャネルとデータチャネルという2つのTCP接続(チャネル)が含まれる場合があります。コマンドチャネルはFTPコマンドの送信に使用され、データチャネルは大量のデータの転送に使用されます。アクティブモードFTPでは、FTPサーバーがFTPクライアントに接続してデータ接続を確立する必要があります。これはセキュリティ上の問題があるとみなされることが多く、多くのファイアウォール/ルーターでブロックされます。パッシブモードFTPでは、FTPクライアントが別のポート番号でFTPサーバーに接続する必要があります。これは安全であると考えられており、ブロックされることはほとんどありません。DriveHQのFTPサーバーは、アクティブFTPとパッシブFTPの両方をサポートしています。ただし、ルーター/ファイアウォールまたはセキュリティソフトウェアがアクティブFTPをブロックしている場合は、動作しません。興味深いことに、最近のルーターのほとんどはアクティブFTPをサポートしています。
ご注意ください:MicrosoftのコマンドラインFTPクライアントはパッシブFTPをサポートしていません。他のほとんどすべてのFTPクライアントプログラムは、アクティブFTPとパッシブFTPの両方をサポートしています。
FTPとProFTP
DriveHQには2つのFTPサイトがあります。1つはftp.drivehq.comで、すべてのユーザーがアクセスできます。もう1つはproftp.drivehq.comで、有料会員(有料グループアカウントのサブユーザーを含む)のみが利用できます。proftp.drivehq.comは有料会員のみが利用できるため、匿名FTPはサポートしていません。FTPサーバーホスティングサービスの詳細については、こちらをご覧ください:
http://www.drivehq.com/servicemanual.aspx#_Toc265186728
サンプルFTPクライアントソースコード
以下のC#ソースコードは、サポートなしで現状のまま提供されます。ご自身のソフトウェアに組み込んだり、再配布したりすることは自由です。サンプルコードは、当社のFTPサーバーに接続し、LIST、GET、PUTなどのFTPコマンドを実行する方法を示しています。また、パッシブFTPとSSLを使用するように設定する方法も確認できます。
using System;
System.Collections.Generic を使用します。
System.Linq を使用します。
System.Text を使用します。
System.Threading.Tasks を使用します。
System.Net を使用します。
System.IO を使用します。
System.Security.Cryptography.X509Certificates を使用します。
/// <概要>
/// 著作権 (c) 2003-2016、Drive Headquarters, Inc.
///
/// このFTPクライアントのサンプルコードは、C#を使用してDriveHQのFTPサーバーに接続する方法を示しています。
/// このコードは無料で使用または再配布できます。コードは現状のまま提供されます
/// サポートや保証は一切ありません。DriveHQは、コードの使用に関して一切の責任を負いません。
///
名前空間 FTPClientSample
{
クラスプログラム
{
static string ftpServer = "ftp.drivehq.com"; // 有料アカウントをお持ちの場合は、proftp.drivehq.com も使用できます。
static string username = "YOUR_USERNAME"; // DriveHQ のユーザー名
static string password = "YOUR_PASSWORD"; // DriveHQ のパスワード
static void Main(string[] args)
{
// FTPサーバー上のフォルダを一覧表示する
//リスト("/");
// FTPサーバーからファイルをダウンロードする
//DownloadFile("ServerFileName.jpg", @"c:\temp\ClientFileName.jpg");
// ファイルをFTPサーバーにアップロードする
UploadFile(@"c:\temp\ClientFileName.jpg", "/temp/ServerFileName.jpg");
}
/// <概要>
/// ファイルをFTPサーバーにアップロードしてください。
///
/// FTPサーバー上のパス(例:/temp/filename)
///
public static bool UploadFile(string srcFilePath, string destFilePath = null)
{
if (String.IsNullOrWhiteSpace(srcFilePath))
throw new ArgumentNullException("ソースファイルパス.");
if (String.IsNullOrWhiteSpace(destFilePath))
destFilePath = Path.GetFileName(srcFilePath);
Uri サーバーUri = GetUri(destFilePath);
// serverUri は ftp:// スキームで始まる必要があります。
if (serverUri.Scheme != Uri.UriSchemeFtp)
falseを返す。
FtpWebRequest request = CreateFtpRequest(serverUri, WebRequestMethods.Ftp.UploadFile);
// ファイルの内容をバイト配列に読み込む
FileStream sourceStream = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read);
byte[] fileContent = new byte[sourceStream.Length];
sourceStream.Read(fileContent, 0, fileContent.Length);
sourceStream.Close();
// ファイルの内容をFTPサーバーに送信する
request.ContentLength = fileContent.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContent, 0, fileContent.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("応答ステータス: {0} - {1}", response.StatusCode, response.StatusDescription);
trueを返します。
}
/// <概要>
/// FTPサーバー上のsrcFilePathをdestFilePathにダウンロードします。nullの場合は、現在のフォルダに保存します。
///
///
public static bool DownloadFile(string srcFilePath, string destFilePath = null)
{
if (String.IsNullOrWhiteSpace(srcFilePath))
throw new ArgumentNullException("ソースファイルパス.");
if (String.IsNullOrWhiteSpace(destFilePath))
destFilePath = Path.GetFileName(srcFilePath);
Uri サーバーUri = GetUri(srcFilePath);
//// serverUri は ftp:// スキームで始まる必要があります。
if (serverUri.Scheme != Uri.UriSchemeFtp)
falseを返す。
FtpWebRequest request = CreateFtpRequest(serverUri, WebRequestMethods.Ftp.DownloadFile);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream fileStream = new FileStream(destFilePath, FileMode.OpenOrCreate, FileAccess.Write);
byte[] buffer = new byte[32 * 1024];
while(true) {
int bytesRead = responseStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
壊す;
fileStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
Console.WriteLine("応答ステータス: {0} - {1}", response.StatusCode, response.StatusDescription);
trueを返します。
}
/// <概要>
/// FTPフォルダの内容を一覧表示する
///
///
public static string List(string path)
{
Uri serverUri = GetUri(path);
//// serverUri は ftp:// スキームで始まる必要があります。
if (serverUri.Scheme != Uri.UriSchemeFtp)
戻る "";
FtpWebRequest request = CreateFtpRequest(serverUri, WebRequestMethods.Ftp.ListDirectory);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string result = sr.ReadToEnd();
Console.WriteLine("応答ステータス: {0} - {1}", response.StatusCode, response.StatusDescription + "\r\n" + result);
結果を返す。
}
private static FtpWebRequest CreateFtpRequest(Uri serverUri, string method)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.EnableSsl = true;
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true;
request.Credentials = new NetworkCredential(username, password);
request.Method = method;
リクエストを返します。
}
private static Uri GetUri(string remoteFilePath)
{
Uri ftpServerUri = new Uri("ftp://" + ftpServer);
return new Uri(ftpServerUri, remoteFilePath);
}
}
}