这里将使用在Winform平台上搭建FTP的通讯。
[项目源码]
链接:https://pan.baidu.com/s/1oPwGmFy9JIwgBNhQa4fcNg
提取码:v2he
复制这段内容后打开百度网盘手机App,操作更方便哦
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using FTP.Model;
using System.Threading.Tasks;
namespace FTP.Base
{
public class FtpClient
{
private const int BUFFSIZE = 1024 * 2;
public string ServerIP { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string URI { get; set; }
public Action CompleteDownload = null;
public Action CompleteUpload = null;
public Action<string> FailDownload = null;
public Action<string> FailUpload = null;
/// <summary>
/// 设置FTP属性
/// </summary>
/// <param name="FtpServerIP">FTP连接地址</param>
/// <param name="this.UserName">用户名</param>
/// <param name="Password">密码</param>
public FtpClient(string serverIP, string userName, string passwordName)
{
this.ServerIP = serverIP;
this.UserName = userName;
this.Password = passwordName;
this.URI = "ftp://" + this.ServerIP + "/";
}
/// <summary>
/// 上传
/// </summary>
/// <param name="relativePath">服务器的相对路径</param>
/// <param name="localPath">本地文件的绝对路径</param>
public void Upload(string relativePath, string localPath)
{
try
{
Task task = Task.Factory.StartNew(() =>
{
UploadFile(relativePath, localPath);
});
task.ContinueWith(t =>
{
if (task.Exception == null)
{
if (this.CompleteUpload != null)
this.CompleteUpload();
}
else if (this.FailUpload != null)
{
this.FailUpload(task.Exception.Message);
}
});
}
catch (Exception ex)
{
if (this.FailUpload != null)
this.FailUpload(ex.Message);
}
finally
{
}
}
private void UploadFile(string relativePath, string localPath)
{
FtpWebRequest reqFTP = null;
FileStream fs = null;
Stream strm = null;
try
{
FileInfo fileInf = new FileInfo(localPath);
string uri = this.URI + relativePath + "/" + Path.GetFileName(localPath);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
reqFTP.ContentLength = fileInf.Length;
byte[] buff = new byte[BUFFSIZE];
int contentLen = 0;
fs = fileInf.OpenRead();
strm = reqFTP.GetRequestStream();
while ((contentLen = fs.Read(buff, 0, buff.Length)) != 0)
{
strm.Write(buff, 0, contentLen);
}
if (this.CompleteUpload != null)
this.CompleteUpload();
}
finally
{
if (reqFTP != null)
reqFTP.Abort();
if (fs != null)
fs.Close();
if (strm != null)
strm.Close();
}
}
/// <summary>
/// 下载
/// </summary>
/// <param name="filePath">本地保存路径</param>
/// <param name="fileName">需要下载的FTP服务器路径上的文件名,同时也是本地保存的文件名</param>
public void Download(string filePath, string serverPath, string fileName)
{
try
{
Task task = Task.Factory.StartNew(() =>
{
DownloadFile(filePath, serverPath, fileName);
});
task.ContinueWith(t =>
{
if (task.Exception == null)
{
if (this.CompleteDownload != null)
this.CompleteDownload();
}
else if (this.FailDownload != null)
{
List<string> ex = new List<string>();
foreach (var item in t.Exception.InnerExceptions)
{
ex.Add(item.Message);
}
this.FailDownload(string.Join("\n", ex));
}
});
}
catch (Exception ex)
{
if (this.FailDownload != null)
this.FailDownload(ex.Message);
}
finally
{
}
}
private void DownloadFile(string filePath, string serverPath, string fileName)
{
FtpWebRequest ftpRequest = null;
FileStream outputStream = null;
FtpWebResponse response = null;
Stream ftpStream = null;
try
{
outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
string uri = this.URI + serverPath + "/" + fileName;
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = false;
ftpRequest.Proxy = null;
ftpRequest.Credentials = new NetworkCredential(this.UserName, this.Password);
response = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = response.GetResponseStream();
//long needRead = response.ContentLength, realRead = 0; // 出现response.ContentLength=-1但仍能下载的情况,原因?
int readCount = 0;
byte[] buffer = new byte[BUFFSIZE];
while ((readCount = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, readCount);
//realRead += readCount;
}
}
finally
{
if (ftpRequest != null)
ftpRequest.Abort();
if (ftpStream != null)
ftpStream.Close();
if (response != null)
response.Close();
if (outputStream != null)
outputStream.Close();
}
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="fileName"></param>
public void Delete(string fileName)
{
try
{
string uri = this.URI + fileName;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
reqFTP.UsePassive = false;
string result = String.Empty;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
long size = response.ContentLength;
Stream datastream = response.GetResponseStream();
StreamReader sr = new StreamReader(datastream);
result = sr.ReadToEnd();
sr.Close();
datastream.Close();
response.Close();
}
catch (Exception ex)
{
throw new Exception("FtpHelper Delete Error --> " + ex.Message + " 文件名:" + fileName);
}
}
/// <summary>
/// 删除文件夹
/// </summary>
/// <param name="folderName"></param>
public void RemoveDirectory(string folderName)
{
try
{
string uri = this.URI + folderName;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory;
reqFTP.UsePassive = false;
string result = String.Empty;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
long size = response.ContentLength;
Stream datastream = response.GetResponseStream();
StreamReader sr = new StreamReader(datastream);
result = sr.ReadToEnd();
sr.Close();
datastream.Close();
response.Close();
}
catch (Exception ex)
{
throw new Exception("FtpHelper Delete Error --> " + ex.Message + " 文件名:" + folderName);
}
}
/// <summary>
/// 获取当前目录下明细(包含文件和文件夹),并按文件种类排序(文件在前,文件夹在后)
/// </summary>
/// <param name="path">相对FTP根目录的路径</param>
/// <returns></returns>
public List<FtpFileModel> GetFilesDetailList(string path = "")
{
Console.WriteLine(path);
FtpWebRequest ftp = null;
WebResponse response = null;
StreamReader reader = null;
List<FtpFileModel> fileList = new List<FtpFileModel>();
try
{
StringBuilder result = new StringBuilder();
ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.URI + path));
ftp.Credentials = new NetworkCredential(this.UserName, Password);
ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
ftp.UsePassive = false;
response = ftp.GetResponse();
reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
string line = string.Empty;// 读取的首行内容为"total 0",剔除
while ((line = reader.ReadLine()) != null)
{
try
{
fileList.Add(new FtpFileModel(line, path));
}
catch (Exception)
{
}
}
}
catch (Exception ex)
{
}
finally
{
if (reader != null)
reader.Close();
if (response != null)
response.Close();
if (ftp != null)
ftp.Abort();
}
return fileList.OrderBy(f => f.FileType).ToList();
}
/// <summary>
/// 获取当前目录下文件列表(仅文件)
/// </summary>
/// <returns></returns>
public string[] GetFileList(string mask)
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
FtpWebRequest reqFTP;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.URI));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.UsePassive = false;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
string line = reader.ReadLine();
while (line != null)
{
if (mask.Trim() != string.Empty && mask.Trim() != "*.*")
{
string mask_ = mask.Substring(0, mask.IndexOf("*"));
if (line.Substring(0, mask_.Length) == mask_)
{
result.Append(line);
result.Append("\n");
}
}
else
{
result.Append(line);
result.Append("\n");
}
line = reader.ReadLine();
}
result.Remove(result.ToString().LastIndexOf('\n'), 1);
reader.Close();
response.Close();
return result.ToString().Split('\n');
}
catch (Exception ex)
{
downloadFiles = null;
if (ex.Message.Trim() != "远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)。")
{
throw new Exception("FtpHelper GetFileList Error --> " + ex.Message.ToString());
}
return downloadFiles;
}
}
/// <summary>
/// 判断当前目录下指定的文件是否存在
/// </summary>
/// <param name="RemoteFileName">远程文件名</param>
public bool FileExist(string RemoteFileName)
{
string[] fileList = GetFileList("*.*");
foreach (string str in fileList)
{
if (str.Trim() == RemoteFileName.Trim())
{
return true;
}
}
return false;
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="dirName"></param>
public void MakeDir(string dirName)
{
FtpWebRequest reqFTP;
try
{
// dirName = name of the directory to create.
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.URI + dirName));
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
catch (Exception ex)
{
throw new Exception("FtpHelper MakeDir Error --> " + ex.Message);
}
}
/// <summary>
/// 获取指定文件大小
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public long GetFileSize(string filename)
{
FtpWebRequest reqFTP;
long fileSize = 0;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.URI + filename));
reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
fileSize = response.ContentLength;
ftpStream.Close();
response.Close();
}
catch (Exception ex)
{
throw new Exception("FtpHelper GetFileSize Error --> " + ex.Message);
}
return fileSize;
}
/// <summary>
/// 改名
/// </summary>
/// <param name="currentFilename"></param>
/// <param name="newFilename"></param>
public void ReName(string currentFilename, string newFilename)
{
FtpWebRequest reqFTP;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.URI + currentFilename));
reqFTP.Method = WebRequestMethods.Ftp.Rename;
reqFTP.RenameTo = newFilename;
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
reqFTP.Credentials = new NetworkCredential(this.UserName, Password);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
catch (Exception ex)
{
throw new Exception("FtpHelper ReName Error --> " + ex.Message);
}
}
/// <summary>
/// 移动文件
/// </summary>
/// <param name="currentFilename"></param>
/// <param name="newFilename"></param>
public void MovieFile(string currentFilename, string newDirectory)
{
ReName(currentFilename, newDirectory);
}
}
}
服务器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace FTP.Base
{
public class FtpServer : IDisposable
{
private bool _disposed = false;
private bool _listening = false;
private TcpListener _listener = null;
private List<ClientConnection> _activeConnections = null;
private Dictionary<string, string> _accounts = new Dictionary<string, string>();
public byte[] IP { get; set; }
public int Port { get; set; }
public string RootDirectory { get; set; }
public FtpServer(string ip, int port, string root)
{
string[] ips = ip.Split(".".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
this.IP = new byte[4];
for (int i = 0; i < 4; ++i)
{
this.IP[i] = Convert.ToByte(ips[i]);
}
this.Port = port;
this.RootDirectory = root;
this._accounts["ftptest"] = "123456";
}
public void Start()
{
_listener = new TcpListener(new IPAddress(this.IP), this.Port);
_listener.Start();
_activeConnections = new List<ClientConnection>();
_listening = true;
_listener.BeginAcceptTcpClient(HandleAcceptTcpClient, _listener);
}
public void Stop()
{
_listening = false;
_listener.Stop();
_listener = null;
}
public void AddUser(string userName, string pwd)
{
this._accounts[userName] = pwd;
}
private void HandleAcceptTcpClient(IAsyncResult result)
{
if (_listening)
{
_listener.BeginAcceptTcpClient(HandleAcceptTcpClient, _listener);
TcpClient client = _listener.EndAcceptTcpClient(result);
ClientConnection connection = new ClientConnection(client, this.RootDirectory);
connection.CheckUser = CheckUser;
_activeConnections.Add(connection);
ThreadPool.QueueUserWorkItem(connection.HandleClient, client);
}
}
private bool CheckUser(string userName, string pwd)
{
return this._accounts.ContainsKey(userName) && this._accounts[userName] == pwd;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_listener != null)
{
_listening = false;
_listener.Stop();
}
foreach (ClientConnection conn in _activeConnections)
{
}
}
}
_disposed = true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace FTP.Base
{
internal class ClientConnection
{
private enum DataConnectionType
{
Active,
Passive
}
private TcpClient _controlClient = null;
private TcpClient _dataClient;
private NetworkStream _controlStream = null;
private StreamReader _controlReader = null;
private StreamWriter _controlWriter = null;
private NetworkStream _dataStream = null;
private string _username = null;
private string _transferType = null;
private DataConnectionType _dataConnectionType;
private IPEndPoint _dataEndpoint = null;
private TcpListener _passiveListener = null;
private StreamReader _dataReader = null;
private StreamWriter _dataWriter = null;
private X509Certificate _cert = null;
private SslStream _sslStream = null;
private bool _isLogin = false;
private string _rootDirectory = string.Empty;
private string _currentDirectory = string.Empty;
public Func<string, string, bool> CheckUser = null;
public ClientConnection(TcpClient client, string root)
{
_controlClient = client;
_controlStream = _controlClient.GetStream();
_controlReader = new StreamReader(_controlStream);
_controlWriter = new StreamWriter(_controlStream);
this._rootDirectory = root;
this._currentDirectory = root;
}
public void HandleClient(object obj)
{
_controlWriter.WriteLine("220 Service Ready.");
_controlWriter.Flush();
string line;
try
{
while (!string.IsNullOrEmpty(line = _controlReader.ReadLine()))
{
Console.WriteLine(line);
string response = null;
string[] command = line.Split(' ');
string cmd = command[0].ToUpperInvariant();
string arguments = command.Length > 1 ? line.Substring(command[0].Length + 1) : null;
if (string.IsNullOrWhiteSpace(arguments))
arguments = null;
if (cmd != "USER" && cmd != "PASS" && _isLogin == false)
return;
if (response == null)
{
switch (cmd)
{
case "USER":
response = User(arguments);
break;
case "PASS":
response = Password(arguments);
break;
case "CWD":
response = ChangeWorkingDirectory(arguments);
break;
case "CDUP":
response = ChangeWorkingDirectory("..");
break;
case "PORT":
response = Port(arguments);
break;
case "PASV":
response = Passive();
break;
case "LIST":
response = List(arguments);
break;
case "PWD":
response = "257 \"/\" is current directory.";
break;
case "RETR":
response = Retrieve(arguments);
break;
case "AUTH":
response = Auth(arguments);
break;
case "QUIT":
response = "221 Service closing control connection";
break;
case "TYPE":
string[] splitArgs = arguments.Split(' ');
response = Type(splitArgs[0], splitArgs.Length > 1 ? splitArgs[1] : null);
break;
default:
response = "502 Command not implemented";
break;
}
}
if (_controlClient == null || !_controlClient.Connected)
{
break;
}
else
{
_controlWriter.WriteLine(response);
_controlWriter.Flush();
// Close the connection
if (response.StartsWith("221"))
{
break;
}
if (cmd == "AUTH")
{
_cert = new X509Certificate("server.cer");
_sslStream = new SslStream(_controlStream);
_sslStream.AuthenticateAsServer(_cert);
_controlReader = new StreamReader(_sslStream);
_controlWriter = new StreamWriter(_sslStream);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
#region File System Methods
private static long CopyStream(Stream input, Stream output, int bufferSize)
{
byte[] buffer = new byte[bufferSize];
int count = 0;
long total = 0;
while ((count = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, count);
total += count;
}
return total;
}
private static long CopyStreamAscii(Stream input, Stream output, int bufferSize)
{
char[] buffer = new char[bufferSize];
int count = 0;
long total = 0;
using (StreamReader rdr = new StreamReader(input))
{
using (StreamWriter wtr = new StreamWriter(output, Encoding.UTF8))
{
while ((count = rdr.Read(buffer, 0, buffer.Length)) > 0)
{
wtr.Write(buffer, 0, count);
total += count;
}
}
}
return total;
}
private long CopyStream(Stream input, Stream output)
{
if (_transferType == "I")
{
return CopyStream(input, output, 4096);
}
else
{
return CopyStreamAscii(input, output, 4096);
}
}
private bool IsPathValid(string pathname)
{
return true;
}
private string NormalizeFilename(string pathname)
{
return Path.Combine(_currentDirectory, pathname);
}
#endregion
#region FTP Commands
private string User(string username)
{
_username = username;
return "331 Username ok, need password";
}
private string Password(string password)
{
if (this.CheckUser != null && this.CheckUser(this._username, password))
{
this._isLogin = true;
return "230 User logged in";
}
else
{
this._isLogin = false;
return "530 Not logged in";
}
}
private string Retrieve(string pathname)
{
pathname = NormalizeFilename(pathname);
if (IsPathValid(pathname))
{
if (File.Exists(pathname))
{
if (_dataConnectionType == DataConnectionType.Active)
{
_dataClient = new TcpClient();
_dataClient.BeginConnect(_dataEndpoint.Address, _dataEndpoint.Port, DoRetrieve, pathname);
}
else
{
_passiveListener.BeginAcceptTcpClient(DoRetrieve, pathname);
}
return string.Format("150 Opening {0} mode data transfer for RETR", _dataConnectionType);
}
}
return "550 File Not Found";
}
private string Auth(string authMode)
{
if (authMode == "TLS")
{
return "234 Enabling TLS Connection";
}
else
{
return "504 Unrecognized AUTH mode";
}
}
private string ChangeWorkingDirectory(string pathname)
{
pathname = pathname.TrimStart('/');
pathname = pathname.Replace('/', '\\');
this._currentDirectory = this._rootDirectory + "\\" + pathname;
return "200 Changed to new directory";
}
private string Type(string typeCode, string formatControl)
{
string response = "500 ERROR";
switch (typeCode)
{
case "A":
case "I":
_transferType = typeCode;
response = "200 OK";
break;
case "E":
case "L":
default:
response = "504 Command not implemented for that parameter.";
break;
}
if (formatControl != null)
{
switch (formatControl)
{
case "N":
response = "200 OK";
break;
case "T":
case "C":
default:
response = "504 Command not implemented for that parameter.";
break;
}
}
return response;
}
private string Port(string hostPort)
{
_dataConnectionType = DataConnectionType.Active;
string[] ipAndPort = hostPort.Split(',');
byte[] ipAddress = new byte[4];
byte[] port = new byte[4];
for (int i = 0; i < 4; i++)
{
ipAddress[i] = Convert.ToByte(ipAndPort[i]);
}
for (int i = 4; i < 6; i++)
{
port[i - 4 + 2] = Convert.ToByte(ipAndPort[i]);
}
if (BitConverter.IsLittleEndian)
Array.Reverse(port);
var v1 = new IPAddress(ipAddress);
var v2 = BitConverter.ToInt16(port, 0);
_dataEndpoint = new IPEndPoint(new IPAddress(ipAddress), BitConverter.ToInt32(port, 0));
return "200 Data Connection Established";
}
private string Passive()
{
_dataConnectionType = DataConnectionType.Passive;
IPAddress localAddress = ((IPEndPoint)_controlClient.Client.LocalEndPoint).Address;
_passiveListener = new TcpListener(localAddress, 0);
_passiveListener.Start();
IPEndPoint localEndpoint = ((IPEndPoint)_passiveListener.LocalEndpoint);
byte[] address = localEndpoint.Address.GetAddressBytes();
short port = (short)localEndpoint.Port;
byte[] portArray = BitConverter.GetBytes(port);
if (BitConverter.IsLittleEndian)
Array.Reverse(portArray);
return string.Format("227 Entering Passive Mode ({0},{1},{2},{3},{4},{5})", address[0], address[1], address[2], address[3], portArray[0], portArray[1]);
}
private string List(string pathname)
{
if (pathname == null)
{
pathname = string.Empty;
}
pathname = new DirectoryInfo(Path.Combine(_currentDirectory, pathname)).FullName;
if (IsPathValid(pathname))
{
if (_dataConnectionType == DataConnectionType.Active)
{
_dataClient = new TcpClient();
_dataClient.BeginConnect(_dataEndpoint.Address, _dataEndpoint.Port, DoList, pathname);
}
else
{
_passiveListener.BeginAcceptTcpClient(DoList, pathname);
}
return string.Format("150 Opening {0} mode data transfer for LIST", _dataConnectionType);
}
return "450 Requested file action not taken";
}
#endregion
#region Async Methods
private void DoRetrieve(IAsyncResult result)
{
if (_dataConnectionType == DataConnectionType.Active)
{
_dataClient.EndConnect(result);
}
else
{
_dataClient = _passiveListener.EndAcceptTcpClient(result);
}
string pathname = (string)result.AsyncState;
using (NetworkStream dataStream = _dataClient.GetStream())
{
using (FileStream fs = new FileStream(pathname, FileMode.Open, FileAccess.Read))
{
CopyStream(fs, dataStream);
}
}
_dataClient.Close();
_dataClient = null;
_controlWriter.WriteLine("226 Closing data connection, file transfer successful");
_controlWriter.Flush();
}
private void DoList(IAsyncResult result)
{
if (_dataConnectionType == DataConnectionType.Active)
{
_dataClient.EndConnect(result);
}
else
{
_dataClient = _passiveListener.EndAcceptTcpClient(result);
}
string pathname = (string)result.AsyncState;
using (NetworkStream dataStream = _dataClient.GetStream())
{
_dataReader = new StreamReader(dataStream, Encoding.UTF8);
_dataWriter = new StreamWriter(dataStream, Encoding.UTF8);
IEnumerable<string> directories = Directory.EnumerateDirectories(pathname);
foreach (string dir in directories)
{
DirectoryInfo d = new DirectoryInfo(dir);
string date = d.LastWriteTime < DateTime.Now - TimeSpan.FromDays(180) ?
d.LastWriteTime.ToString("MMM dd yyyy") :
d.LastWriteTime.ToString("MMM dd HH:mm");
string line = string.Format("drwxr-xr-x 2 2003 2003 {0,8} {1} {2}", "4096", date, d.Name);
_dataWriter.WriteLine(line);
_dataWriter.Flush();
}
IEnumerable<string> files = Directory.EnumerateFiles(pathname);
foreach (string file in files)
{
FileInfo f = new FileInfo(file);
string date = f.LastWriteTime < DateTime.Now - TimeSpan.FromDays(180) ?
f.LastWriteTime.ToString("MMM dd yyyy") :
f.LastWriteTime.ToString("MMM dd HH:mm");
string line = string.Format("-rw-r--r-- 2 2003 2003 {0,8} {1} {2}", f.Length, date, f.Name);
_dataWriter.WriteLine(line);
_dataWriter.Flush();
}
}
_dataClient.Close();
_dataClient = null;
_controlWriter.WriteLine("226 Transfer complete");
_controlWriter.Flush();
}
#endregion
}
}