using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions; /*
*解析drwxr-xr-x
*第一位表示文件类型。d是目录文件,l是链接文件,-是普通文件,p是管道
*第2-4位表示这个文件的属主拥有的权限,r是读,w是写,x是执行。
*第5-7位表示和这个文件属主所在同一个组的用户所具有的权限。
*第8-10位表示其他用户所具有的权限。
*例如:
* drwxr-xr-x 1 ftp ftp 0 Mar 02 2011 a安全防护
* -r--r--r-- 1 ftp ftp 27772416 Mar 02 2011 0302
*/
namespace JM_IM_COMP.tool
{
/// <summary>
/// FTP类
/// </summary>
public class FTP
{
#region 变量声明 /// <summary>
/// 服务器连接地址
/// </summary>
public string server; /// <summary>
/// 登陆帐号
/// </summary>
public string user; /// <summary>
/// 登陆口令
/// </summary>
public string pass; /// <summary>
/// 端口号
/// </summary>
public int port; /// <summary>
/// 无响应时间(FTP在指定时间内无响应)
/// </summary>
public int timeout; /// <summary>
/// 服务器错误状态信息
/// </summary>
public string errormessage; /// <summary>
/// 服务器状态返回信息
/// </summary>
private string messages; /// <summary>
/// 服务器的响应信息
/// </summary>
private string responseStr; /// <summary>
/// 链接模式(主动或被动,默认为被动)
/// </summary>
private bool passive_mode; /// <summary>
/// 上传或下载信息字节数
/// </summary>
private long bytes_total; /// <summary>
/// 上传或下载的文件大小
/// </summary>
private long file_size; /// <summary>
/// 主套接字
/// </summary>
private Socket main_sock; /// <summary>
/// 要链接的网络地址终结点
/// </summary>
private IPEndPoint main_ipEndPoint; /// <summary>
/// 侦听套接字
/// </summary>
private Socket listening_sock; /// <summary>
/// 数据套接字
/// </summary>
private Socket data_sock; /// <summary>
/// 要链接的网络数据地址终结点
/// </summary>
private IPEndPoint data_ipEndPoint; /// <summary>
/// 用于上传或下载的文件流对象
/// </summary>
private FileStream file; /// <summary>
/// 与FTP服务器交互的状态值
/// </summary>
private int response; /// <summary>
/// 读取并保存当前命令执行后从FTP服务器端返回的数据信息
/// </summary>
private string bucket; #endregion #region 构造函数 /// <summary>
/// 构造函数
/// </summary>
public FTP()
{
server = null;
user = null;
pass = null;
port = 21;
passive_mode = true;
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; //无响应时间为10秒
messages = "";
errormessage = "";
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="server">服务器IP或名称</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
public FTP(string server, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
port = 21;
passive_mode = true;
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; //无响应时间为10秒
messages = "";
errormessage = "";
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="server">服务器IP或名称</param>
/// <param name="port">端口号</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
public FTP(string server, int port, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port;
passive_mode = true;
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
timeout = 10000; //无响应时间为10秒
messages = "";
errormessage = "";
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="server">服务器IP或名称</param>
/// <param name="port">端口号</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
/// <param name="mode">链接方式</param>
public FTP(string server, int port, string user, string pass, int mode)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port;
passive_mode = mode <= 1 ? true : false;
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
this.timeout = 10000; //无响应时间为10秒
messages = "";
errormessage = "";
} /// <summary>
/// 构造函数
/// </summary>
/// <param name="server">服务器IP或名称</param>
/// <param name="port">端口号</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
/// <param name="mode">链接方式</param>
/// <param name="timeout">无响应时间(限时),单位:秒 (小于或等于0为不受时间限制)</param>
public FTP(string server, int port, string user, string pass, int mode, int timeout_sec)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port;
passive_mode = mode <= 1 ? true : false;
main_sock = null;
main_ipEndPoint = null;
listening_sock = null;
data_sock = null;
data_ipEndPoint = null;
file = null;
bucket = "";
bytes_total = 0;
this.timeout = (timeout_sec <= 0) ? int.MaxValue : (timeout_sec * 1000); //无响应时间
messages = "";
errormessage = "";
} #endregion #region 属性
/// <summary>
/// 当前是否已连接
/// </summary>
public bool IsConnected
{
get
{
if (main_sock != null)
return main_sock.Connected;
return false;
}
} /// <summary>
/// 当message缓冲区有数据则返回
/// </summary>
public bool MessagesAvailable
{
get
{
if (messages.Length > 0)
return true;
return false;
}
} /// <summary>
/// 获取服务器状态返回信息, 并清空messages变量
/// </summary>
public string Messages
{
get
{
string tmp = messages;
messages = "";
return tmp;
}
}
/// <summary>
/// 最新指令发出后服务器的响应
/// </summary>
public string ResponseString
{
get
{
return responseStr;
}
} /// <summary>
///在一次传输中,发送或接收的字节数
/// </summary>
public long BytesTotal
{
get
{
return bytes_total;
}
} /// <summary>
///被下载或上传的文件大小,当文件大小无效时为0
/// </summary>
public long FileSize
{
get
{
return file_size;
}
} /// <summary>
/// 链接模式:
/// true 被动模式 [默认]
/// false: 主动模式
/// </summary>
public bool PassiveMode
{
get
{
return passive_mode;
}
set
{
passive_mode = value;
}
} #endregion #region 操作 /// <summary>
/// 操作失败
/// </summary>
private void Fail()
{
Disconnect();
errormessage += responseStr;
//throw new Exception(responseStr);
} /// <summary>
/// 下载文件类型
/// </summary>
/// <param name="mode">true:二进制文件 false:字符文件</param>
private void SetBinaryMode(bool mode)
{
if (mode)
SendCommand("TYPE I");
else
SendCommand("TYPE A"); ReadResponse();
if (response != 200)
Fail();
} /// <summary>
/// 发送命令
/// </summary>
/// <param name="command"></param>
private void SendCommand(string command)
{
Byte[] cmd = Encoding.Default.GetBytes((command + "\r\n").ToCharArray()); if (command.Length > 3 && command.Substring(0, 4) == "PASS")
{
messages = "\rPASS xxx";
}
else
{
messages = "\r" + command;
} try
{
main_sock.Send(cmd, cmd.Length, 0);
}
catch (Exception ex)
{
try
{
Disconnect();
errormessage += ex.Message;
return;
}
catch
{
main_sock.Close();
file.Close();
main_sock = null;
main_ipEndPoint = null;
file = null;
}
}
} private void FillBucket()
{
Byte[] bytes = new Byte[512];
long bytesgot;
int msecs_passed = 0; while (main_sock.Available < 1)
{
System.Threading.Thread.Sleep(50);
msecs_passed += 50;
//当等待时间到,则断开链接
if (msecs_passed > timeout)
{
Disconnect();
errormessage += "Timed out waiting on server to respond.";
return;
}
} while (main_sock.Available > 0)
{
bytesgot = main_sock.Receive(bytes, 512, 0);
bucket += Encoding.Default.GetString(bytes, 0, (int) bytesgot);
System.Threading.Thread.Sleep(50);
}
} private string GetLineFromBucket()
{
int i;
string buf = ""; if ((i = bucket.IndexOf('\n')) < 0)
{
while (i < 0)
{
FillBucket();
i = bucket.IndexOf('\n');
}
} buf = bucket.Substring(0, i);
bucket = bucket.Substring(i + 1); return buf;
} /// <summary>
/// 返回服务器端返回信息
/// </summary>
private void ReadResponse()
{
string buf;
messages = ""; while (true)
{
buf = GetLineFromBucket(); if (Regex.Match(buf, "^[0-9]+ ").Success)
{
responseStr = buf;
response = int.Parse(buf.Substring(0, 3));
break;
}
else
messages += Regex.Replace(buf, "^[0-9]+-", "") + "\n";
}
} /// <summary>
/// 打开数据套接字
/// </summary>
private void OpenDataSocket()
{
if (passive_mode)
{
string[] pasv;
string server;
int port; Connect();
SendCommand("PASV");
ReadResponse();
if (response != 227)
Fail(); try
{
int i1, i2; i1 = responseStr.IndexOf('(') + 1;
i2 = responseStr.IndexOf(')') - i1;
pasv = responseStr.Substring(i1, i2).Split(',');
}
catch (Exception)
{
Disconnect();
errormessage += "Malformed PASV response: " + responseStr;
return;
} if (pasv.Length < 6)
{
Disconnect();
errormessage += "Malformed PASV response: " + responseStr;
return;
} server = String.Format("{0}.{1}.{2}.{3}", pasv[0], pasv[1], pasv[2], pasv[3]);
port = (int.Parse(pasv[4]) << 8) + int.Parse(pasv[5]); try
{
CloseDataSocket(); data_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); #if NET1
data_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#else
data_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endif data_sock.Connect(data_ipEndPoint); }
catch (Exception ex)
{
errormessage += "Failed to connect for data transfer: " + ex.Message;
return;
}
}
else
{
Connect(); try
{
CloseDataSocket(); listening_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 对于端口,则发送IP地址.下面则提取相应信息
string sLocAddr = main_sock.LocalEndPoint.ToString();
int ix = sLocAddr.IndexOf(':');
if (ix < 0)
{
errormessage += "Failed to parse the local address: " + sLocAddr;
return;
}
string sIPAddr = sLocAddr.Substring(0, ix);
// 系统自动绑定一个端口号(设置 port = 0)
System.Net.IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(sIPAddr), 0); listening_sock.Bind(localEP);
sLocAddr = listening_sock.LocalEndPoint.ToString();
ix = sLocAddr.IndexOf(':');
if (ix < 0)
{
errormessage += "Failed to parse the local address: " + sLocAddr; }
int nPort = int.Parse(sLocAddr.Substring(ix + 1)); // 开始侦听链接请求
listening_sock.Listen(1);
string sPortCmd = string.Format("PORT {0},{1},{2}",
sIPAddr.Replace('.', ','),
nPort / 256, nPort % 256);
SendCommand(sPortCmd);
ReadResponse();
if (response != 200)
Fail();
}
catch (Exception ex)
{
errormessage += "Failed to connect for data transfer: " + ex.Message;
return;
}
}
} private void ConnectDataSocket()
{
if (data_sock != null) // 已链接
return; try
{
data_sock = listening_sock.Accept(); // Accept is blocking
listening_sock.Close();
listening_sock = null; if (data_sock == null)
{
throw new Exception("Winsock error: " +
Convert.ToString(System.Runtime.InteropServices.Marshal.GetLastWin32Error()));
}
}
catch (Exception ex)
{
errormessage += "Failed to connect for data transfer: " + ex.Message;
}
} private void CloseDataSocket()
{
if (data_sock != null)
{
if (data_sock.Connected)
{
data_sock.Close();
}
data_sock = null;
} data_ipEndPoint = null;
} /// <summary>
/// 关闭所有链接
/// </summary>
public void Disconnect()
{
CloseDataSocket(); if (main_sock != null)
{
if (main_sock.Connected)
{
SendCommand("QUIT");
main_sock.Close();
}
main_sock = null;
} if (file != null)
file.Close(); main_ipEndPoint = null;
file = null;
} /// <summary>
/// 链接到FTP服务器
/// </summary>
/// <param name="server">要链接的IP地址或主机名</param>
/// <param name="port">端口号</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
public void Connect(string server, int port, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass;
this.port = port; Connect();
} /// <summary>
/// 链接到FTP服务器
/// </summary>
/// <param name="server">要链接的IP地址或主机名</param>
/// <param name="user">登陆帐号</param>
/// <param name="pass">登陆口令</param>
public void Connect(string server, string user, string pass)
{
this.server = server;
this.user = user;
this.pass = pass; Connect();
} /// <summary>
/// 链接到FTP服务器
/// </summary>
public bool Connect()
{
if (server == null)
{
errormessage += "No server has been set.\r\n";
}
if (user == null)
{
errormessage += "No server has been set.\r\n";
} if (main_sock != null)
if (main_sock.Connected)
return true; try
{
main_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#if NET1
main_ipEndPoint = new IPEndPoint(Dns.GetHostByName(server).AddressList[0], port);
#else
main_ipEndPoint = new IPEndPoint(System.Net.Dns.GetHostEntry(server).AddressList[0], port);
#endif main_sock.Connect(main_ipEndPoint);
}
catch (Exception ex)
{
errormessage += ex.Message;
return false;
} ReadResponse();
if (response != 220)
Fail(); SendCommand("USER " + user);
ReadResponse(); switch (response)
{
case 331:
if (pass == null)
{
Disconnect();
errormessage += "No password has been set.";
return false;
}
SendCommand("PASS " + pass);
ReadResponse();
if (response != 230)
{
Fail();
return false;
}
break;
case 230:
break;
} return true;
} /// <summary>
/// 获取FTP当前(工作)目录下的文件列表
/// </summary>
/// <returns>返回文件列表数组</returns>
public ArrayList List()
{
Byte[] bytes = new Byte[512];
string file_list = "";
long bytesgot = 0;
int msecs_passed = 0;
ArrayList list = new ArrayList(); Connect();
OpenDataSocket();
SendCommand("LIST");
ReadResponse(); switch (response)
{
case 125:
case 150:
break;
default:
CloseDataSocket();
throw new Exception(responseStr);
}
ConnectDataSocket(); while (data_sock.Available < 1)
{
System.Threading.Thread.Sleep(50);
msecs_passed += 50; if (msecs_passed > (timeout / 10))
{
break;
}
} while (data_sock.Available > 0)
{
bytesgot = data_sock.Receive(bytes, bytes.Length, 0);
//file_list += Encoding.ASCII.GetString(bytes, 0, (int) bytesgot);
file_list += Encoding.Default.GetString(bytes, 0, (int)bytesgot);
System.Threading.Thread.Sleep(50);
} CloseDataSocket(); ReadResponse();
if (response != 226)
throw new Exception(responseStr); foreach (string f in file_list.Split('\n'))
{
if (f.Length > 0 && !Regex.Match(f, "^total").Success)
list.Add(f.Substring(0, f.Length - 1));
} return list;
} /// <summary>
/// 获取到文件名列表
/// </summary>
/// <returns>返回文件名列表</returns>
public ArrayList ListFiles()
{
ArrayList list = new ArrayList(); foreach (string f in List())
{
if ((f.Length > 0))
{
if ((f[0] != 'd') && (f.ToUpper().IndexOf("<DIR>") < 0))
list.Add(f);
}
} return list;
} /// <summary>
/// 获取路径列表
/// </summary>
/// <returns>返回路径列表</returns>
public ArrayList ListDirectories()
{
ArrayList list = new ArrayList(); foreach (string f in List())
{
if (f.Length > 0)
{
if ((f[0] == 'd') || (f.ToUpper().IndexOf("<DIR>") >= 0))
list.Add(f);
}
} return list;
} /// <summary>
/// 获取原始数据信息.
/// </summary>
/// <param name="fileName">远程文件名</param>
/// <returns>返回原始数据信息.</returns>
public string GetFileDateRaw(string fileName)
{
Connect(); SendCommand("MDTM " + fileName);
ReadResponse();
if (response != 213)
{
errormessage += responseStr;
return "";
} return (this.responseStr.Substring(4));
} /// <summary>
/// 得到文件日期.
/// </summary>
/// <param name="fileName">远程文件名</param>
/// <returns>返回远程文件日期</returns>
public DateTime GetFileDate(string fileName)
{
return ConvertFTPDateToDateTime(GetFileDateRaw(fileName));
} private DateTime ConvertFTPDateToDateTime(string input)
{
if (input.Length < 14)
throw new ArgumentException("Input Value for ConvertFTPDateToDateTime method was too short."); //YYYYMMDDhhmmss":
int year = Convert.ToInt16(input.Substring(0, 4));
int month = Convert.ToInt16(input.Substring(4, 2));
int day = Convert.ToInt16(input.Substring(6, 2));
int hour = Convert.ToInt16(input.Substring(8, 2));
int min = Convert.ToInt16(input.Substring(10, 2));
int sec = Convert.ToInt16(input.Substring(12, 2)); return new DateTime(year, month, day, hour, min, sec);
} /// <summary>
/// 获取FTP上的当前(工作)路径
/// </summary>
/// <returns>返回FTP上的当前(工作)路径</returns>
public string GetWorkingDirectory()
{
//PWD - 显示工作路径
Connect();
SendCommand("PWD");
ReadResponse(); if (response != 257)
{
errormessage += responseStr;
} string pwd;
try
{
pwd = responseStr.Substring(responseStr.IndexOf("\"", 0) + 1);//5);
pwd = pwd.Substring(0, pwd.LastIndexOf("\""));
pwd = pwd.Replace("\"\"", "\""); // 替换带引号的路径信息符号
}
catch (Exception ex)
{
errormessage += ex.Message;
return null;
} return pwd;
} /// <summary>
/// 跳转服务器上的当前(工作)路径
/// </summary>
/// <param name="path">要跳转的路径</param>
public bool ChangeDir(string path)
{
Connect();
SendCommand("CWD " + path);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
return false;
}
return true;
} /// <summary>
/// 创建指定的目录
/// </summary>
/// <param name="dir">要创建的目录</param>
public void MakeDir(string dir)
{
Connect();
SendCommand("MKD " + dir);
ReadResponse(); switch (response)
{
case 257:
case 250:
break;
default:
{
errormessage += responseStr;
break;
}
}
} /// <summary>
/// 移除FTP上的指定目录
/// </summary>
/// <param name="dir">要移除的目录</param>
public void RemoveDir(string dir)
{
Connect();
SendCommand("RMD " + dir);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
return;
;
}
} /// <summary>
/// 移除FTP上的指定文件
/// </summary>
/// <param name="filename">要移除的文件名称</param>
public void RemoveFile(string filename)
{
Connect();
SendCommand("DELE " + filename);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
}
} /// <summary>
/// 重命名FTP上的文件
/// </summary>
/// <param name="oldfilename">原文件名</param>
/// <param name="newfilename">新文件名</param>
public void RenameFile(string oldfilename, string newfilename)
{
Connect();
SendCommand("RNFR " + oldfilename);
ReadResponse();
if (response != 350)
{
errormessage += responseStr;
}
else
{
SendCommand("RNTO " + newfilename);
ReadResponse();
if (response != 250)
{
errormessage += responseStr;
}
}
} /// <summary>
/// 获得指定文件的大小(如果FTP支持)
/// </summary>
/// <param name="filename">指定的文件</param>
/// <returns>返回指定文件的大小</returns>
public long GetFileSize(string filename)
{
Connect();
SendCommand("SIZE " + filename);
ReadResponse();
if (response != 213)
{
errormessage += responseStr;
} return Int64.Parse(responseStr.Substring(4));
} /// <summary>
/// 上传指定的文件
/// </summary>
/// <param name="filename">要上传的文件</param>
public bool OpenUpload(string filename)
{
return OpenUpload(filename, filename, false);
} /// <summary>
/// 上传指定的文件
/// </summary>
/// <param name="filename">本地文件名</param>
/// <param name="remotefilename">远程要覆盖的文件名</param>
public bool OpenUpload(string filename, string remotefilename)
{
return OpenUpload(filename, remotefilename, false);
} /// <summary>
/// 上传指定的文件
/// </summary>
/// <param name="filename">本地文件名</param>
/// <param name="resume">如果存在,则尝试恢复</param>
public bool OpenUpload(string filename, bool resume)
{
return OpenUpload(filename, filename, resume);
} /// <summary>
/// 上传指定的文件
/// </summary>
/// <param name="filename">本地文件名</param>
/// <param name="remote_filename">远程要覆盖的文件名</param>
/// <param name="resume">如果存在,则尝试恢复</param>
public bool OpenUpload(string filename, string remote_filename, bool resume)
{
Connect();
SetBinaryMode(true);
OpenDataSocket(); bytes_total = 0; try
{
file = new FileStream(filename, FileMode.Open);
}
catch (Exception ex)
{
file = null;
errormessage += ex.Message;
return false;
} file_size = file.Length; if (resume)
{
long size = GetFileSize(remote_filename);
SendCommand("REST " + size);
ReadResponse();
if (response == 350)
file.Seek(size, SeekOrigin.Begin);
} SendCommand("STOR " + remote_filename);
ReadResponse(); switch (response)
{
case 125:
case 150:
break;
default:
file.Close();
file = null;
errormessage += responseStr;
return false;
}
ConnectDataSocket(); return true;
} /// <summary>
/// 下载指定文件
/// </summary>
/// <param name="filename">远程文件名称</param>
public void OpenDownload(string filename)
{
OpenDownload(filename, filename, false);
} /// <summary>
/// 下载并恢复指定文件
/// </summary>
/// <param name="filename">远程文件名称</param>
/// <param name="resume">如文件存在,则尝试恢复</param>
public void OpenDownload(string filename, bool resume)
{
OpenDownload(filename, filename, resume);
} /// <summary>
/// 下载指定文件
/// </summary>
/// <param name="filename">远程文件名称</param>
/// <param name="localfilename">本地文件名</param>
public void OpenDownload(string remote_filename, string localfilename)
{
OpenDownload(remote_filename, localfilename, false);
} /// <summary>
/// 打开并下载文件
/// </summary>
/// <param name="remote_filename">远程文件名称</param>
/// <param name="local_filename">本地文件名</param>
/// <param name="resume">如果文件存在则恢复</param>
public void OpenDownload(string remote_filename, string local_filename, bool resume)
{
Connect();
SetBinaryMode(true); bytes_total = 0; try
{
file_size = GetFileSize(remote_filename);
}
catch
{
file_size = 0;
} if (resume && File.Exists(local_filename))
{
try
{
file = new FileStream(local_filename, FileMode.Open);
}
catch (Exception ex)
{
file = null;
throw new Exception(ex.Message);
} SendCommand("REST " + file.Length);
ReadResponse();
if (response != 350)
throw new Exception(responseStr);
file.Seek(file.Length, SeekOrigin.Begin);
bytes_total = file.Length;
}
else
{
try
{
file = new FileStream(local_filename, FileMode.Create);
}
catch (Exception ex)
{
file = null;
throw new Exception(ex.Message);
}
} OpenDataSocket();
SendCommand("RETR " + remote_filename);
ReadResponse(); switch (response)
{
case 125:
case 150:
break;
default:
file.Close();
file = null;
errormessage += responseStr;
return;
}
ConnectDataSocket(); return;
} /// <summary>
/// 上传文件(循环调用直到上传完毕)
/// </summary>
/// <returns>发送的字节数</returns>
public long DoUpload()
{
Byte[] bytes = new Byte[512];
long bytes_got; try
{
bytes_got = file.Read(bytes, 0, bytes.Length);
bytes_total += bytes_got;
data_sock.Send(bytes, (int) bytes_got, 0); if (bytes_got <= 0)
{
//上传完毕或有错误发生
file.Close();
file = null; CloseDataSocket();
ReadResponse();
switch (response)
{
case 226:
case 250:
break;
default: //当上传中断时
{
errormessage += responseStr;
return -1;
}
} SetBinaryMode(false);
}
}
catch (Exception ex)
{
file.Close();
file = null;
CloseDataSocket();
ReadResponse();
SetBinaryMode(false);
//throw ex;
//当上传中断时
errormessage += ex.Message;
return -1;
} return bytes_got;
} /// <summary>
/// 下载文件(循环调用直到下载完毕)
/// </summary>
/// <returns>接收到的字节点</returns>
public long DoDownload()
{
Byte[] bytes = new Byte[512];
long bytes_got; try
{
bytes_got = data_sock.Receive(bytes, bytes.Length, 0); if (bytes_got <= 0)
{
//下载完毕或有错误发生
CloseDataSocket();
file.Close();
file = null; ReadResponse();
switch (response)
{
case 226:
case 250:
break;
default:
{
errormessage += responseStr;
return -1;
}
} //SetBinaryMode(false);
SetBinaryMode(true);//业务需要,使用二进制模式下载
return bytes_got;
} file.Write(bytes, 0, (int) bytes_got);
bytes_total += bytes_got;
}
catch (Exception ex)
{
CloseDataSocket();
file.Close();
file = null;
ReadResponse();
SetBinaryMode(false);
//throw ex;
//当下载中断时
errormessage += ex.Message;
return -1;
} return bytes_got;
} #endregion
}
}

使用例子:

using System;
using System.Collections;
using System.IO;
using Discuz.Common; namespace Test
{
class TestFtp
{
public void Test()
{
FTP ftp = new FTP("127.0.0.1", "abc", "123456"); //建立文件夹
ftp.MakeDir("com");
ftp.ChangeDir("com");
ftp.MakeDir("mzwu");
ftp.ChangeDir("mzwu"); //文件夹列表
ArrayList list = ftp.ListDirectories();
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i].ToString() + "<br/>");
} //删除文件夹(不能直接删除非空文件夹)
ftp.RemoveDir("com\\mzwu"); //上传文件
ftp.Connect();
ftp.OpenUpload(@"F:\mzwucom.jpg", Path.GetFileName(@"F:\mzwucom.jpg"));
while (ftp.DoUpload() > 0)
{
int perc = (int) (((ftp.BytesTotal) * 100) / ftp.FileSize);
Console.WriteLine(perc.ToString() + "%<br/>");
}
ftp.Disconnect(); //下载文件
ftp.Connect();
ftp.OpenDownload("mzwucom.jpg", @"E:\mzwucom.jpg");
while (ftp.DoDownload() > 0)
{
int perc = (int) (((ftp.BytesTotal) * 100) / ftp.FileSize);
Console.WriteLine(perc.ToString() + "%<br/>");
}
ftp.Disconnect(); //文件列表
list = ftp.ListFiles();
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i].ToString() + "<br/>");
} //文件重命名
ftp.RenameFile("mzwucom.jpg", "test.jpg"); //删除文件
ftp.RemoveFile("test.jpg"); //显示错误信息
Console.WriteLine(ftp.errormessage);
} }
}

C#使用Sockets操作FTP【转载】的更多相关文章

  1. C#使用Sockets操作FTP

    http://blog.csdn.net/foart/article/details/6824551 using System; using System.Collections; using Sys ...

  2. 使用python操作FTP上传和下载

    函数释义 Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,函数列举如下 ftp登陆连接 from ftplib import F ...

  3. C#操作FTP报错,远程服务器返回错误:(550)文件不可用(例如,未找到文件,无法访问文件)的解决方法

    最近在做项目的时候需要操作ftp进行文件的上传下载,但在调用using (var response = (FtpWebResponse)FtpWebRequest.GetResponse())的时候总 ...

  4. Asp.Net操作FTP方法

    将用户上传的附件(文件.图片等)通过FTP方式传送到另外一台服务器上,从而缓解服务器压力 1.相关的文章如下: Discuz!NT中远程附件的功能实现[FTP协议] http://www.cnblog ...

  5. java操作FTP的一些工具方法

    java操作FTP还是很方便的,有多种开源支持,这里在apache开源的基础上自己进行了一些设计,使用起来更顺手和快捷. 思路: 1.设计FTPHandler接口,可以对ftp,sftp进行统一操作, ...

  6. 【转】 C#操作FTP

    代码不要忘记引入命名空间using System.Net;using System.IO;下面的几个步骤包括了使用FtpWebRequest类实现ftp功能的一般过程1.创建一个FtpWebReque ...

  7. C# 操作FTP

    操作FTP管理类: using System; using System.Collections.Generic; using System.Text; using System.Net; using ...

  8. ftp客户端自动同步 Windows系统简单操作ftp客户端自动同步

    服务器管理工具它是一款功能强大的服务器集成管理器,包含win系统和linux系统的批量连接,vnc客户端,ftp客户端等等实用功能.我们可以使用这款软件的ftp客户端定时上传下载的功能来进实现ftp客 ...

  9. [PHP学习教程 - 类库]002.FTP操作(FTP)

    引言:FTP是大家上传至站点服务器必须要使用的协议.现在常用的FTP客户端工具也很多,如:8uftp,FlashFXP,....但是使用客户端工具就无法真正与自动化联系起来.所以今天,我们为大家讲一下 ...

随机推荐

  1. Swift(三.函数)

    一.swift中的函数分为以下几类吧 1>无参无返   2>无参有返 3>有参无返  4>有参有返  5>有参多返 二.看下面几个例子吧 1>无参无返 func a ...

  2. linux常用命令搜索

    解压tar - xzvf webcmp.tar.gz /目的目录 压缩tar - czvf webcmp.tar.gz /压缩源文件 发包命令 cd /cap/sc_bossdata_20140516 ...

  3. MySQL下Limit使用及性能分析

    对于一直用Oracle的我,今天可是非常诧异,MySQL中同一个函数在不同数量级上的性能居然差距如此之大. 先看表ibmng(id,title,info)  唯一  id key 索引title 先看 ...

  4. C# 两时间,时间间隔

    #region 返回时间差        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)        {  ...

  5. Swift2.0新特性

    随着刚刚结束的 WWDC 2015 苹果发布了一系列更新,这其中就包括了令人振奋的 Swift 2.0. 这是对之前语言特性的一次大幅的更新,加入了很多实用和方便的元素,下面我们就一起来看看这次更新都 ...

  6. Java设计模式之——单例模式

    引自百度百科: 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类. 通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系 ...

  7. 第一次写Makefile文件

    test.c文件内容 #include <stdio.h> int main(int argc, char const *argv[]) { printf("hahahah\n& ...

  8. [HDOJ 5212] [BestCoder Round#39] Code 【0.0】

    题目链接:HDOJ - 5212 题目分析 首先的思路是,考虑每个数对最终答案的贡献. 那么我们就要求出:对于每个数,以它为 gcd 的数对有多少对. 显然,对于一个数 x ,以它为 gcd 的两个数 ...

  9. 防御XSS攻击的七条原则

    本文将会着重介绍防御XSS攻击的一些原则,需要读者对于XSS有所了解,至少知道XSS漏洞的基本原理,如果您对此不是特别清楚,请参考这两篇文章:<Stored and Reflected XSS ...

  10. phpStorm 配置关联php手册

    phpStorm 配置关联php手册 pasting php开发中我尝试过很多个编辑器,但用的最多的是phpStorm ,但一直因为英文太烂,很多phpStorm功能,都没用过.. 最近发现有些编辑器 ...