c#上传下载ftp(支持断点续传) using System; using System.Net; using System.IO; using System.Text; using System.Net.Sockets; namespace ftpGet { /**////
/// FTP Client /// public class FTPClient { 构造函数#region 构造函数 /**////
/// 缺省构造函数 /// public FTPClient() { strRemoteHost = ""; strRemotePath = ""; strRemoteUser = ""; strRemotePass = ""; strRemotePort = 21; bConnected = false; } /**////
/// 构造函数 /// ///
FTP服务器IP地址 ///
当前服务器目录 ///
登录用户账号 ///
登录用户密码 ///
FTP服务器端口 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 登陆字段、属性 /**////
/// FTP服务器IP地址 /// private string strRemoteHost; public string RemoteHost { get { return strRemoteHost; } set { strRemoteHost = value; } } /**////
/// FTP服务器端口 /// private int strRemotePort; public int RemotePort { get { return strRemotePort; } set { strRemotePort = value; } } /**////
/// 当前服务器目录 /// private string strRemotePath; public string RemotePath { get { return strRemotePath; } set { strRemotePath = value; } } /**////
/// 登录用户账号 /// private string strRemoteUser; public string RemoteUser { set { strRemoteUser = value; } } /**////
/// 用户登录密码 /// private string strRemotePass; public string RemotePass { set { strRemotePass = value; } } /**////
/// 是否登录 /// private Boolean bConnected; public bool Connected { get { return bConnected; } } #endregion 链接#region 链接 /**////
/// 建立连接 /// public void Connect() { 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("Couldn't connect to remote server"); } // 获取应答码 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; // 切换到初始目录 if (!string.IsNullOrEmpty(strRemotePath)) { ChDir(strRemotePath); } } /**////
/// 关闭连接 /// public void DisConnect() { if (socketControl != null) { SendCommand("QUIT"); } CloseSocketConnect(); } #endregion 传输模式#region 传输模式 /**////
/// 传输模式:二进制类型、ASCII类型 /// public enum TransferType { Binary, ASCII }; /**////
/// 设置传输模式 /// ///
传输模式 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; } } /**////
/// 获得传输模式 /// ///
传输模式 public TransferType GetTransferType() { return trType; } #endregion 文件操作#region 文件操作 /**////
/// 获得文件列表 /// ///
文件名的匹配字符串 ///
public string[] Dir(string strMask) { // 建立链接 if (!bConnected) { Connect(); } //建立进行数据连接的socket Socket socketData = CreateDataSocket(); //传送命令 SendCommand("LIST " + strMask); //分析应答代码 if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226)) { throw new IOException(strReply.Substring(4)); } //获得结果 strMsg = ""; while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); strMsg += GB2312.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 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; } /**////
/// 删除 /// ///
待删除文件名 public void Delete(string strFileName) { if (!bConnected) { Connect(); } SendCommand("DELE " + strFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /**////
/// 重命名(如果新文件名与已有文件重名,将覆盖已有文件) /// ///
旧文件名 ///
新文件名 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 上传和下载 /**////
/// 下载一批文件 /// ///
文件名的匹配字符串 ///
本地目录(不得以\结束) public void Get(string strFileNameMask, string strFolder) { if (!bConnected) { Connect(); } string[] strFiles = Dir(strFileNameMask); foreach (string strFile in strFiles) { if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串 { if (strFile.LastIndexOf(".") > -1) { Get(strFile.Replace("\r", ""), strFolder, strFile.Replace("\r", "")); } } } } /**////
/// 下载目录 /// ///
要下载的文件名 ///
本地目录(不得以\结束) ///
保存在本地时的文件名 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName) { if (strLocalFileName.StartsWith("-r")) { string[] infos = strLocalFileName.Split(' '); strRemoteFileName=strLocalFileName = infos[infos.Length - 1]; if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName; } if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName); st.Close(); } FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create); Socket socketData = CreateDataSocket(); 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)); } } } } /**////
/// 下载一个文件 /// ///
要下载的文件名 ///
本地目录(不得以\结束) ///
保存在本地时的文件名 public void GetFile(string strRemoteFileName, string strFolder, string strLocalFileName) { if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName; } if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName); st.Close(); } FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create); Socket socketData = CreateDataSocket(); 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)); } } } /**////
/// 下载一个文件 /// ///
要下载的文件名 ///
本地目录(不得以\结束) ///
保存在本地时的文件名 public void GetBrokenFile(string strRemoteFileName, string strFolder, string strLocalFileName,long size) { if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Append); Socket socketData = CreateDataSocket(); SendCommand("REST " + size.ToString()); SendCommand("RETR " + strRemoteFileName); if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } //int byteYu = (int)size % 512; //int byteChu = (int)size / 512; //byte[] tempBuffer = new byte[byteYu]; //for (int i = 0; i < byteChu; i++) //{ // socketData.Receive(buffer, buffer.Length, 0); //} //socketData.Receive(tempBuffer, tempBuffer.Length, 0); //socketData.Receive(buffer, byteYu, 0); while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); //totalBytes += iBytes; 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)); } } } /**////
/// 上传一批文件 /// ///
本地目录(不得以\结束) ///
文件名匹配字符(可以包含*和?) public void Put(string strFolder, string strFileNameMask) { string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask); foreach (string strFile in strFiles) { //strFile是完整的文件名(包含路径) Put(strFile); } } /**////
/// 上传一个文件 /// ///
本地文件名 public void Put(string strFileName) { if (!bConnected) { Connect(); } Socket socketData = CreateDataSocket(); 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)); } } } #endregion 目录操作#region 目录操作 /**////
/// 创建目录 /// ///
目录名 public void MkDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("MKD " + strDirName); if (iReplyCode != 257) { throw new IOException(strReply.Substring(4)); } } /**////
/// 删除目录 /// ///
目录名 public void RmDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("RMD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /**////
/// 改变目录 /// ///
新的工作目录名 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 内部变量 /**////
/// 服务器返回的应答信息(包含应答码) /// private string strMsg; /**////
/// 服务器返回的应答信息(包含应答码) /// private string strReply; /**////
/// 服务器返回的应答码 ///