1、ftpclient 类

  public class FTPClient:IDisposable
{
public static object _obj = new object(); #region 构造函数
/// <summary>
/// 缺省构造函数
/// </summary>
public FTPClient()
{
_strRemoteHost = "";
_strRemotePath = "";
_strRemoteUser = "";
_strRemotePass = "";
_strRemotePort = 21;
_bConnected = false;
} /// <summary>
/// 构造函数
/// </summary>
public FTPClient(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort)
{
_strRemoteHost = remoteHost;
_strRemotePath = remotePath;
_strRemoteUser = remoteUser;
_strRemotePass = remotePass;
_strRemotePort = remotePort;
Connect();
}
#endregion #region 字段
private int _strRemotePort;
private Boolean _bConnected;
private string _strRemoteHost;
private string _strRemotePass;
private string _strRemoteUser;
private string _strRemotePath; /// <summary>
/// 服务器返回的应答信息(包含应答码)
/// </summary>
private string _strMsg;
/// <summary>
/// 服务器返回的应答信息(包含应答码)
/// </summary>
private string _strReply;
/// <summary>
/// 服务器返回的应答码
/// </summary>
private int _iReplyCode;
/// <summary>
/// 进行控制连接的socket
/// </summary>
private Socket _socketControl;
/// <summary>
/// 传输模式
/// </summary>
private TransferType _trType;
/// <summary>
/// 接收和发送数据的缓冲区
/// </summary>
private static int _BLOCK_SIZE = 512;
/// <summary>
/// 编码方式
/// </summary>
Encoding _ASCII = Encoding.UTF8;
/// <summary>
/// 字节数组
/// </summary>
Byte[] _buffer = new Byte[_BLOCK_SIZE];
#endregion #region 属性
/// <summary>
/// FTP服务器IP地址
/// </summary>
public string RemoteHost
{
get
{
return _strRemoteHost;
}
set
{
_strRemoteHost = value;
}
} /// <summary>
/// FTP服务器端口
/// </summary>
public int RemotePort
{
get
{
return _strRemotePort;
}
set
{
_strRemotePort = value;
}
} /// <summary>
/// 当前服务器目录
/// </summary>
public string RemotePath
{
get
{
return _strRemotePath;
}
set
{
_strRemotePath = value;
}
} /// <summary>
/// 登录用户账号
/// </summary>
public string RemoteUser
{
set
{
_strRemoteUser = value;
}
} /// <summary>
/// 用户登录密码
/// </summary>
public string RemotePwd
{
set
{
_strRemotePass = value;
}
} /// <summary>
/// 是否登录
/// </summary>
public bool Connected
{
get
{
return _bConnected;
}
}
#endregion #region 链接
/// <summary>
/// 建立连接
/// </summary>
public void Connect()
{
lock (_obj)
{
_socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), _strRemotePort);
try
{
_socketControl.Connect(ep);
}
catch (Exception)
{
throw new IOException("不能连接ftp服务器");
}
}
ReadReply();
if (_iReplyCode != 220)
{
DisConnect();
throw new IOException(_strReply.Substring(4));
}
SendCommand("USER " + _strRemoteUser);
if (!(_iReplyCode == 331 || _iReplyCode == 230))
{
CloseSocketConnect();
throw new IOException(_strReply.Substring(4));
}
if (_iReplyCode != 230)
{
SendCommand("PASS " + _strRemotePass);
if (!(_iReplyCode == 230 || _iReplyCode == 202))
{
CloseSocketConnect();
throw new IOException(_strReply.Substring(4));
}
}
_bConnected = true;
ChDir(_strRemotePath);
} /// <summary>
/// 关闭连接
/// </summary>
public void DisConnect()
{
if (_socketControl != null)
{
SendCommand("QUIT");
}
CloseSocketConnect();
}
#endregion #region 传输模式
/// <summary>
/// 传输模式:二进制类型、ASCII类型
/// </summary>
public enum TransferType { Binary, ASCII }; /// <summary>
/// 设置传输模式
/// </summary>
/// <param name="ttType">传输模式</param>
public void SetTransferType(TransferType ttType)
{
if (ttType == TransferType.Binary)
{
SendCommand("TYPE I");//binary类型传输
}
else
{
SendCommand("TYPE A");//ASCII类型传输
}
if (_iReplyCode != 200)
{
throw new IOException(_strReply.Substring(4));
}
else
{
_trType = ttType;
}
} /// <summary>
/// 获得传输模式
/// </summary>
/// <returns>传输模式</returns>
public TransferType GetTransferType()
{
return _trType;
}
#endregion #region 文件操作
/// <summary>
/// 获得文件列表
/// </summary>
/// <param name="strMask">文件名的匹配字符串</param>
public string[] Dir(string strMask)
{
if (!_bConnected)
{
Connect();
}
Socket socketData = CreateDataSocket();
SendCommand("NLST " + strMask);
if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226))
{
throw new IOException(_strReply.Substring(4));
}
_strMsg = "";
Thread.Sleep(2000);
while (true)
{
int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
_strMsg += _ASCII.GetString(_buffer, 0, iBytes);
if (iBytes < _buffer.Length)
{
break;
}
}
char[] seperator = { '\n' };
string[] strsFileList = _strMsg.Split(seperator);
socketData.Close(); //数据socket关闭时也会有返回码
if (_iReplyCode != 226)
{
ReadReply();
if (_iReplyCode != 226)
{ throw new IOException(_strReply.Substring(4));
}
}
return strsFileList;
} public void newPutByGuid(string strFileName, string strGuid)
{
if (!_bConnected)
{
Connect();
}
string str = strFileName.Substring(0, strFileName.LastIndexOf("\\"));
string strTypeName = strFileName.Substring(strFileName.LastIndexOf("."));
strGuid = str + "\\" + strGuid;
Socket socketData = CreateDataSocket();
SendCommand("STOR " + Path.GetFileName(strGuid));
if (!(_iReplyCode == 125 || _iReplyCode == 150))
{
throw new IOException(_strReply.Substring(4));
}
FileStream input = new FileStream(strGuid, FileMode.Open);
input.Flush();
int iBytes = 0;
while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
{
socketData.Send(_buffer, iBytes, 0);
}
input.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
} /// <summary>
/// 获取文件大小
/// 当文件在ftp服务器上不存在时,报异常
/// </summary>
/// <param name="strFileName">文件名</param>
/// <returns>文件大小</returns>
public long GetFileSize(string strFileName)
{
if (!_bConnected)
{
Connect();
}
SendCommand("SIZE " + Path.GetFileName(strFileName));
long lSize = 0;
if (_iReplyCode == 213)
{
lSize = Int64.Parse(_strReply.Substring(4));
}
else
{
throw new IOException(_strReply.Substring(4));
}
return lSize;
} /// <summary>
/// 获取文件信息
/// </summary>
/// <param name="strFileName">文件名</param>
/// <returns>文件大小</returns>
public string GetFileInfo(string strFileName)
{
if (!_bConnected)
{
Connect();
}
Socket socketData = CreateDataSocket();
SendCommand("LIST " + strFileName);
string strResult = "";
if (!(_iReplyCode == 150 || _iReplyCode == 125
|| _iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
byte[] b = new byte[512];
MemoryStream ms = new MemoryStream(); while (true)
{
int iBytes = socketData.Receive(b, b.Length, 0);
ms.Write(b, 0, iBytes);
if (iBytes <= 0)
{ break;
}
}
byte[] bt = ms.GetBuffer();
strResult = System.Text.Encoding.ASCII.GetString(bt);
ms.Close();
return strResult;
} /// <summary>
/// 删除
/// </summary>
/// <param name="strFileName">待删除文件名</param>
public void Delete(string strFileName)
{
if (!_bConnected)
{
Connect();
}
SendCommand("DELE " + strFileName);
if (_iReplyCode != 250)
{
throw new IOException(_strReply.Substring(4));
}
} /// <summary>
/// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
/// </summary>
/// <param name="strOldFileName">旧文件名</param>
/// <param name="strNewFileName">新文件名</param>
public void Rename(string strOldFileName, string strNewFileName)
{
if (!_bConnected)
{
Connect();
}
SendCommand("RNFR " + strOldFileName);
if (_iReplyCode != 350)
{
throw new IOException(_strReply.Substring(4));
}
// 如果新文件名与原有文件重名,将覆盖原有文件
SendCommand("RNTO " + strNewFileName);
if (_iReplyCode != 250)
{
throw new IOException(_strReply.Substring(4));
}
}
#endregion #region 上传和下载
/// <summary>
/// 下载一批文件
/// </summary>
/// <param name="strFileNameMask">文件名的匹配字符串</param>
/// <param name="strFolder">本地目录(不得以\结束)</param>
public void Get(string strFileNameMask, string strFolder)
{
if (!_bConnected)
{
Connect();
}
string[] strFiles = Dir(strFileNameMask);
foreach (string strFile in strFiles)
{
if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串
{
Get(strFile, strFolder, strFile);
}
}
} /// <summary>
/// 下载一个文件
/// </summary>
/// <param name="strRemoteFileName">要下载的文件名</param>
/// <param name="strFolder">本地目录(不得以\结束)</param>
/// <param name="strLocalFileName">保存在本地时的文件名</param>
public void Get(string strRemoteFileName, string strFolder, string strLocalFileName="")
{
Socket socketData = CreateDataSocket();
try
{
if (!_bConnected)
{
Connect();
}
SetTransferType(TransferType.Binary); strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName); SendCommand("RETR " + strRemoteFileName);
if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);
while (true)
{
int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
output.Write(_buffer, 0, iBytes);
if (iBytes <= 0)
{
break;
}
}
output.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
}
catch
{
socketData.Close();
socketData = null;
_socketControl.Close();
_bConnected = false;
_socketControl = null;
}
} /// <summary>
/// 下载一个文件,支持断点下载
/// </summary>
/// <param name="strRemoteFileName"></param>
/// <param name="strFolder"></param>
/// <param name="strLocalFileName"></param>
/// <param name="size"></param>
public void GetBrokenFile(string strRemoteFileName, string strFolder, string strLocalFileName="")
{
if (!_bConnected)
{
Connect();
}
SetTransferType(TransferType.Binary); strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName); long localFileSize = 0;
var localfileWithFullname = strFolder + "//" + strLocalFileName;
if (File.Exists(localfileWithFullname))
{
FileInfo fInfo = new FileInfo(localfileWithFullname);
localFileSize = fInfo.Length;
}
else
{
throw new Exception("localfile not exists!");
} FileStream output = new
FileStream(strFolder + "//" + strLocalFileName, FileMode.Append);
Socket socketData = CreateDataSocket();
SendCommand("REST " + localFileSize.ToString());
SendCommand("RETR " + strRemoteFileName);
if (!(_iReplyCode == 150 || _iReplyCode == 125
|| _iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
} while (true)
{
int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
output.Write(_buffer, 0, iBytes);
if (iBytes <= 0)
{
break;
}
}
output.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
} /// <summary>
/// 下载一个文件 ,智能判断是重新下载或者断点继续下载
/// 1、当本地文件不存在,或者大小等于0, 重新下载
/// 2、当本地文件存在, size>0 and size<totalsize, 断点下载
/// </summary>
/// <param name="strRemoteFileName"></param>
/// <param name="strFolder"></param>
/// <param name="strLocalFileName"></param>
public void GetFileByRestartOrBroken(string strRemoteFileName, string strFolder, string strLocalFileName = "")
{
strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName);
long remoteFileSize = 0;
long localFileSize = 0;
try
{
remoteFileSize = this.GetFileSize(strRemoteFileName);
}
catch (Exception ex)
{
throw new IOException(string.Format("由于 {0} 导致 GetFileByRestartOrBroken 出现异常", ex.Message));
} var localfileWithFullname = strFolder + "//" + strLocalFileName;
if (File.Exists(localfileWithFullname))
{
FileInfo fInfo = new FileInfo(localfileWithFullname);
localFileSize = fInfo.Length;
}
else
{
localFileSize = 0;
} if (localFileSize==0)
{
this.Get(strRemoteFileName, strFolder, strLocalFileName);
}
else
{
this.GetBrokenFile(strRemoteFileName, strFolder,strLocalFileName);
}
} /// <summary>
/// 下载一个文件
/// </summary>
/// <param name="strRemoteFileName">要下载的文件名</param>
/// <param name="strFolder">本地目录(不得以\结束)</param>
/// <param name="strLocalFileName">保存在本地时的文件名</param>
public void GetNoBinary(string strRemoteFileName, string strFolder, string strLocalFileName="")
{
if (!_bConnected)
{
Connect();
} strLocalFileName = RegetFileName(strRemoteFileName, strLocalFileName); Socket socketData = CreateDataSocket();
SendCommand("RETR " + strRemoteFileName);
if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);
while (true)
{
int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
output.Write(_buffer, 0, iBytes);
if (iBytes <= 0)
{
break;
}
}
output.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
} /// <summary>
/// 上传一批文件
/// </summary>
/// <param name="strFolder">本地目录(不得以\结束)</param>
/// <param name="strFileNameMask">文件名匹配字符(可以包含*和?)</param>
public void Put(string strFolder, string strFileNameMask)
{
string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask);
foreach (string strFile in strFiles)
{
Put(strFile);
}
} /// <summary>
/// 上传一个文件
/// </summary>
/// <param name="strFileName">本地文件名 fullName</param>
public void Put(string strFileName)
{
if (!_bConnected)
{
Connect();
}
Socket socketData = CreateDataSocket();
if (Path.GetExtension(strFileName) == "")
SendCommand("STOR " + Path.GetFileNameWithoutExtension(strFileName));
else
SendCommand("STOR " + Path.GetFileName(strFileName)); if (!(_iReplyCode == 125 || _iReplyCode == 150))
{
throw new IOException(_strReply.Substring(4));
} FileStream input = new FileStream(strFileName, FileMode.Open);
int iBytes = 0;
while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
{
socketData.Send(_buffer, iBytes, 0);
}
input.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
} /// <summary>
/// 上传一个文件,支持断点上传
/// </summary>
/// <param name="strFileName">localfile with fullName</param>
/// <param name="remoteFileName">remoteFilename</param>
public void PutBrokenFile(string strFileName,string remoteFileName="")
{
if (!_bConnected)
{
Connect();
}
remoteFileName = RegetFileName(strFileName, remoteFileName); long remotefileSize = 0;
try
{
remotefileSize= this.GetFileSize(remoteFileName);
}
catch (Exception ex)
{
throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常",ex.Message));
} try
{
if (!File.Exists(strFileName))
{
throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常","待上传的文件不存在"));
} var fInfo = new FileInfo(strFileName);
var localFilesize = fInfo.Length;
if (localFilesize < remotefileSize)
{
throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常", "本地文件小于服务器文件 ,不能再断点上传"));
}
}
catch (Exception ex)
{
throw new IOException(string.Format("由于 {0} 导致 PutBrokenFile 出现异常", ex.Message));
} Socket socketData = CreateDataSocket();
if (Path.GetExtension(strFileName) == "")
SendCommand("APPE " + Path.GetFileNameWithoutExtension(strFileName));
else
SendCommand("APPE " + Path.GetFileName(strFileName)); if (!(_iReplyCode == 125 || _iReplyCode == 150))
{
throw new IOException(_strReply.Substring(4));
} FileStream input = new FileStream(strFileName, FileMode.Open);
input.Seek(remotefileSize, SeekOrigin.Begin);
int iBytes = 0;
while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
{
socketData.Send(_buffer, iBytes, 0);
}
input.Close();
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
} /// <summary>
/// 上传一个文件 ,智能判断是重新上传或者断点续传
/// 1、当ftp服务器文件不存在,或者大小等于0, 重新下载
/// 2、当ftp服务器文件存在, size>0 and size<totalsize, 断点续传
/// </summary>
/// <param name="localFileName">localfile with fullname</param>
/// <param name="remoteFileName">remote file name </param>
public void PutFileByRestartOrBroken(string localFileName, string remoteFileName = "")
{
remoteFileName = RegetFileName(localFileName, remoteFileName);
long remoteFileSize = 0;
long localFileSize = 0;
try
{
remoteFileSize = this.GetFileSize(remoteFileName);
}
catch (Exception ex)
{
remoteFileSize = 0;
} if (File.Exists(localFileName))
{
FileInfo fInfo = new FileInfo(localFileName);
localFileSize = fInfo.Length;
}
else
{
localFileSize = 0;
} if (remoteFileSize == 0)
{
this.Put(localFileName);
}
else
{
this.PutBrokenFile(localFileName, remoteFileName);
}
} private static string RegetFileName(string strFileName, string strNullOrNo)
{
string rtnString = "";
if (string.IsNullOrEmpty(strNullOrNo))
{
if (Path.GetExtension(strFileName) == "")
{
rtnString = Path.GetFileNameWithoutExtension(strFileName);
}
else
{
rtnString = Path.GetFileName(strFileName);
}
}
else
{
rtnString = strNullOrNo;
}
return rtnString;
} /// <summary>
/// 上传一个文件
/// </summary>
/// <param name="strFileName">本地文件名</param>
public void PutByGuid(string strFileName, string strGuid)
{
if (!_bConnected)
{
Connect();
}
string str = strFileName.Substring(0, strFileName.LastIndexOf("\\"));
string strTypeName = strFileName.Substring(strFileName.LastIndexOf("."));
strGuid = str + "\\" + strGuid;
System.IO.File.Copy(strFileName, strGuid);
System.IO.File.SetAttributes(strGuid, System.IO.FileAttributes.Normal);
Socket socketData = CreateDataSocket();
SendCommand("STOR " + Path.GetFileName(strGuid));
if (!(_iReplyCode == 125 || _iReplyCode == 150))
{
throw new IOException(_strReply.Substring(4));
}
FileStream input = new FileStream(strGuid, FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
int iBytes = 0;
while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
{
socketData.Send(_buffer, iBytes, 0);
}
input.Close();
File.Delete(strGuid);
if (socketData.Connected)
{
socketData.Close();
}
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
ReadReply();
if (!(_iReplyCode == 226 || _iReplyCode == 250))
{
throw new IOException(_strReply.Substring(4));
}
}
}
#endregion #region 目录操作
/// <summary>
/// 创建目录
/// </summary>
/// <param name="strDirName">目录名</param>
public void MkDir(string strDirName)
{
if (!_bConnected)
{
Connect();
}
SendCommand("MKD " + strDirName);
if (_iReplyCode != 257)
{
throw new IOException(_strReply.Substring(4));
}
} /// <summary>
/// 删除目录
/// </summary>
/// <param name="strDirName">目录名</param>
public void RmDir(string strDirName)
{
if (!_bConnected)
{
Connect();
}
SendCommand("RMD " + strDirName);
if (_iReplyCode != 250)
{
throw new IOException(_strReply.Substring(4));
}
} /// <summary>
/// 改变目录
/// </summary>
/// <param name="strDirName">新的工作目录名</param>
public void ChDir(string strDirName)
{
if (strDirName.Equals(".") || strDirName.Equals(""))
{
return;
}
if (!_bConnected)
{
Connect();
}
SendCommand("CWD " + strDirName);
if (_iReplyCode != 250)
{
throw new IOException(_strReply.Substring(4));
}
this._strRemotePath = strDirName;
}
#endregion #region 内部函数
/// <summary>
/// 将一行应答字符串记录在strReply和strMsg,应答码记录在iReplyCode
/// </summary>
private void ReadReply()
{
_strMsg = "";
_strReply = ReadLine();
_iReplyCode = Int32.Parse(_strReply.Substring(0, 3));
} /// <summary>
/// 建立进行数据连接的socket
/// </summary>
/// <returns>数据连接socket</returns>
private Socket CreateDataSocket()
{
SendCommand("PASV");
if (_iReplyCode != 227)
{
throw new IOException(_strReply.Substring(4));
}
int index1 = _strReply.IndexOf('(');
int index2 = _strReply.IndexOf(')');
string ipData = _strReply.Substring(index1 + 1, index2 - index1 - 1);
int[] parts = new int[6];
int len = ipData.Length;
int partCount = 0;
string buf = "";
for (int i = 0; i < len && partCount <= 6; i++)
{
char ch = Char.Parse(ipData.Substring(i, 1));
if (Char.IsDigit(ch))
buf += ch;
else if (ch != ',')
{
throw new IOException("Malformed PASV strReply: " + _strReply);
}
if (ch == ',' || i + 1 == len)
{
try
{
parts[partCount++] = Int32.Parse(buf);
buf = "";
}
catch (Exception)
{
throw new IOException("Malformed PASV strReply: " + _strReply);
}
}
}
string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
int port = (parts[4] << 8) + parts[5];
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ipAddress), port);
try
{
s.Connect(ep);
}
catch (Exception)
{
throw new IOException("无法连接ftp服务器");
}
return s;
} /// <summary>
/// 关闭socket连接(用于登录以前)
/// </summary>
private void CloseSocketConnect()
{
lock (_obj)
{
if (_socketControl != null)
{
_socketControl.Close();
_socketControl = null;
}
_bConnected = false;
}
} /// <summary>
/// 读取Socket返回的所有字符串
/// </summary>
/// <returns>包含应答码的字符串行</returns>
private string ReadLine()
{
lock (_obj)
{
while (true)
{
int iBytes = _socketControl.Receive(_buffer, _buffer.Length, 0);
_strMsg += _ASCII.GetString(_buffer, 0, iBytes);
if (iBytes < _buffer.Length)
{
break;
}
}
}
char[] seperator = { '\n' };
string[] mess = _strMsg.Split(seperator);
if (_strMsg.Length > 2)
{
_strMsg = mess[mess.Length - 2];
}
else
{
_strMsg = mess[0];
}
if (!_strMsg.Substring(3, 1).Equals(" ")) //返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
{
return ReadLine();
}
return _strMsg;
} /// <summary>
/// 发送命令并获取应答码和最后一行应答字符串
/// </summary>
/// <param name="strCommand">命令</param>
public void SendCommand(String strCommand)
{
lock (_obj)
{
// Byte[] cmdBytes = Encoding.ASCII.GetBytes((strCommand + "\r\n").ToCharArray());
Byte[] cmdBytes = _ASCII.GetBytes((strCommand + "\r\n").ToCharArray());
_socketControl.Send(cmdBytes, cmdBytes.Length, 0);
Thread.Sleep(500);
ReadReply();
}
}
#endregion public void Dispose()
{
this.DisConnect();
}
}

  2、 测试代码

 class Program
{
static void Main(string[] args)
{
// FtpFirstTest();
// GetBrokenFileTest();
// FileSizeTest();
// FtpPutBrokenFile(); // SmartGet(); SmartPutFile(); Console.WriteLine("ftp finished");
Console.ReadKey();
} private static void FtpFirstTest()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
// ftp.Put("D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");
Console.WriteLine("ftp operation");
ftp.GetNoBinary("[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb", "D:\\programShareFile", "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");
}
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
}
} /// <summary>
/// 断点下载测试
/// </summary>
static void GetBrokenFileTest()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
//Console.WriteLine("ftp operation ing");
//ftp.Put("D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb");
//Console.WriteLine("ftp operation");
var localfile = "D:\\programShareFile\\apicloudFtp.zip";
if (File.Exists(localfile))
{
FileInfo fInfo = new FileInfo(localfile);
var size = fInfo.Length;
Console.WriteLine("file now size=" + size.ToString());
ftp.GetBrokenFile("apicloudFtp.zip", "D:\\programShareFile", "apicloudFtp.zip");
}
else
{
Console.WriteLine("file not exists");
}
}
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
} } /// <summary>
/// 获取ftp服务器文件大小 测试。 存在的文件 ,不存在的文件
/// </summary>
static void FileSizeTest()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
Console.WriteLine("ftp operation");
var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb"; var remoteFile = "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb";
var remoteFile2 = "apicloudFtp22.zip"; try
{
var size = ftp.GetFileSize(remoteFile2);
Console.WriteLine(string.Format("file size={0}",size));
}
catch (Exception ex)
{
Console.WriteLine("ftp getfilesize exception ");
} }
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
}
} /// <summary>
/// 测试 ftp 断点上传
/// </summary>
static void FtpPutBrokenFile()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
Console.WriteLine("ftp operation");
var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb"; var remoteFile = "apicloudFtp.zip"; try
{
ftp.PutBrokenFile(localfile, "");
}
catch (Exception ex)
{
Console.WriteLine("ftp.PutBrokenFile exception ");
}
}
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
}
} /// <summary>
/// 智能下载测试
/// </summary>
static void SmartGet()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
Console.WriteLine("ftp operation");
// var localfile = "D:\\programShareFile\\apicloudFtp.zip"; ftp.GetFileByRestartOrBroken("[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb", "D:\\programShareFile", "[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb"); }
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
}
} static void SmartPutFile()
{
var ftpServer = ConfigurationSettings.AppSettings["ftpServer"];
var ftpPort = ConfigurationSettings.AppSettings["ftpPort"];
var userName = ConfigurationSettings.AppSettings["userName"];
var pwd = ConfigurationSettings.AppSettings["pwd"]; try
{
using (var ftp = new FTPClient(ftpServer, "/", userName, pwd, int.Parse(ftpPort)))
{
if (!ftp.Connected)
{
ftp.Connect();
}
Console.WriteLine("ftp operation");
var localfile = "D:\\programShareFile\\[阳光电影www.ygdy8.com].44号孩子.BD.720p.中英双字幕.rmvb"; try
{
ftp.PutFileByRestartOrBroken(localfile);
}
catch (Exception ex)
{
Console.WriteLine("ftp.PutBrokenFile exception ");
}
}
}
catch (Exception ex)
{
Console.WriteLine("ftp exception msg:" + ex.Message);
}
}
}

  3 config配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="ftpServer" value="127.0.0.1"/>
<add key="ftpPort" value="21"/>
<add key="userName" value="hyt"/>
<add key ="pwd" value="hyt"/>
</appSettings>
</configuration>

  4  使用到 filezilla server   ftp服务器。测试正常工作

5  为了更加方便的理解ftp原理,附上ftp命令和响应值文档

FTP命令字和响应码解释

FTP命令

命令     描述
ABOR 中断数据连接程序
ACCT <account> 系统特权帐号
ALLO <bytes> 为服务器上的文件存储器分配字节
APPE <filename> 添加文件到服务器同名文件
CDUP <dir path> 改变服务器上的父目录
CWD <dir path> 改变服务器上的工作目录
DELE <filename> 删除服务器上的指定文件
HELP <command> 返回指定命令信息
LIS2T <name> 如果是文件名列出文件信息,如果是目录则列出文件列表
MODE <mode> 传输模式(S=流模式,B=块模式,C=压缩模式)
MKD <directory> 在服务器上建立指定目录
NLST <directory> 列出指定目录内容
NOOP 无动作,除了来自服务器上的承认
PASS <password> 系统登录密码
PASV 请求服务器等待数据连接
PORT <address> IP 地址和两字节的端口 ID
PWD 显示当前工作目录
QUIT 从 FTP 服务器上退出登录
REIN 重新初始化登录状态连接
REST <offset> 由特定偏移量重启文件传递
RETR <filename> 从服务器上找回(复制)文件
RMD <directory> 在服务器上删除指定目录
RNFR <old path> 对旧路径重命名
RNTO <new path> 对新路径重命名
SITE <params> 由服务器提供的站点特殊参数
SMNT <pathname> 挂载指定文件结构
STAT <directory> 在当前程序或目录上返回信息
STOR <filename> 储存(复制)文件到服务器上
STOU <filename> 储存文件到服务器名称上
STRU <type> 数据结构(F=文件,R=记录,P=页面)
SYST 返回服务器使用的操作系统
TYPE <data type> 数据类型(A=ASCII,E=EBCDIC,I=binary)
USER <username>> 系统登录的用户名 FTP响应码 响应代码 解释说明
110 新文件指示器上的重启标记
120 服务器准备就绪的时间(分钟数)
125 打开数据连接,开始传输
150 打开连接
200 成功
202 命令没有执行
211 系统状态回复
212 目录状态回复
213 文件状态回复
214 帮助信息回复
215 系统类型回复
220 服务就绪
221 退出网络
225 打开数据连接
226 结束数据连接
227 进入被动模式(IP 地址、ID 端口)
230 登录因特网
250 文件行为完成
257 路径名建立
331 要求密码
332 要求帐号
350 文件行为暂停
421 服务关闭
425 无法打开数据连接
426 结束连接
450 文件不可用
451 遇到本地错误
452 磁盘空间不足
500 无效命令
501 错误参数
502 命令没有执行
503 错误指令序列
504 无效命令参数
530 未登录网络
532 存储文件需要帐号
550 文件不可用
551 不知道的页类型
552 超过存储分配
553 文件名不允许

ftp 操作,支持断点续传或者继续下载。的更多相关文章

  1. FTP文件上传 支持断点续传 并 打印下载进度(二) —— 单线程实现

    这个就看代码,哈哈哈哈哈  需要用到的jar包是: <dependency> <groupId>commons-net</groupId> <artifact ...

  2. edtftpj让Java上传FTP文件支持断点续传

    在用Java实现FTP上传文件功能时,特别是上传大文件的时候,可以需要这样的功能:程序在上传的过程中意外终止了,文件传了一大半,想从断掉了地方继续传:或者想做类似迅雷下载类似的功能,文件太大,今天传一 ...

  3. webuploader-异步切片上传(暂不支持断点续传)及 下载方法!C#/.NET

    十年河东,十年河西,莫欺少年穷 学无止境,精益求精 进入正题: 关于webuploader,参考网址:https://fex.baidu.com/webuploader/: 本篇博客范例下载地址:ht ...

  4. C# http下载(支持断点续传)

    分享下项目里面自己封装的一个http下载类 功能如下: 1.支持断点续传 2.下载失败自动重试 3.超时等异常处理 using System; using System.Collections.Gen ...

  5. 设置IIS7/IIS7.5的FTP支持断点续传

    Windows Server 2003的IIS自带FTP默认支持断点续传,但是Windows Server 2008/R2默认已经不支持,因此需要注意设置,才能让其支持断点续传,更好的利用宝贵的服务器 ...

  6. php大文件下载支持断点续传

    <?php   /** php下载类,支持断点续传  *  *   Func:  *   download: 下载文件  *   setSpeed: 设置下载速度  *   getRange: ...

  7. 【FTP】FTP文件上传下载-支持断点续传

    Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...

  8. c#上传下载ftp(支持断点续传)

    using System;using System.Net;using System.IO;using System.Text;using System.Net.Sockets;namespace f ...

  9. Spring Boot Ftp Client 客户端示例支持断点续传

    本章介绍 Spring Boot 整合 Ftpclient 的示例,支持断点续传 本项目源码下载 1 新建 Spring Boot Maven 示例工程项目 注意:是用来 IDEA 开发工具 File ...

随机推荐

  1. Spring MVC开发环境的搭建和实例

    一.安装jdk 二.安装tomcat 三.安装maven 新增环境变量MAVEN-HOME,并在path变量中添加bin路径 四.安装IntelliJ IDEA 五.创建maven web项目选择jd ...

  2. SPI数据传输(库函数方法)

    主机端: /********************************* 代码功能:SPI数据传输(主机端) 引脚说明: SS/CS:片选(高电平屏蔽,低电平启用) MOSI :主机送出信号 M ...

  3. hdu 3661 Assignments (贪心)

    Assignments Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. vagrant 安装使用 win7

    第一步.安装VirtualBox和vagrant 下载地址: https://www.virtualbox.org/wiki/Downloads http://downloads.vagrantup. ...

  5. javascript第四节其它引用对象

    单体对象 Global对象(全局)这个对象不存在,无形的对象 其内部定义了一些方法和属性:encodeURL.encodeURIComponent.decodeURI.decodeURICompone ...

  6. python 迭代器和生成器

    1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)2.可迭代对象:实现了迭代器协议的 ...

  7. servers中添加server时,看不到运行环境的选择。

    servers中添加server时,看不到运行环境的选择. 主要原因是tomcat目录中的配置文件格式不对.

  8. java的面向对象

    Java是1995年诞生.前身oak,后来改名为java. 面向对象的编程思想:对象是万事万物. 对象是由两部分组成的:属性和方法 1:属性是对象的静态特性(名词) 2:方法是对象的动态特性(动词) ...

  9. php获得ip地址

    方法一: <?phpfunction GetIP(){if(!empty($_SERVER["HTTP_CLIENT_IP"])){ $cip = $_SERVER[&quo ...

  10. java环境配置总结

    最近接触java,在环境配置上费了不少劲.总结一下: 1.首先安装jdk和Eclipse,jdk我安装的是1.6,Eclipse可以从官网下载:http://download.eclipse.org/ ...