手记

C#的FTP服务器源代码


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

//**new namespace

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Resources;

using System.Text.RegularExpressions;

using System.Collections;

namespace crFTP

{

    /// <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.ASCII.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.ASCII.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);

                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);

                    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

    }

}

/////////////////////////////////////////////////////////上述FTP类应用方法如下//////////////////////////////////

 FTP ftp = new FTP("172.16.22.251", "hegaoji", "cstchgj");

            //建立文件夹

     

        ftp.MakeDir("test");

            ftp.ChangeDir("test");

            ftp.MakeDir("test1");

            ftp.ChangeDir("test1");

            ArrayList list =   ftp.ListDirectories();

           ftp.RemoveDir("test\\test1");

            //上传文件

             ftp.Connect();

             ftp.OpenUpload(@"G:\dotNetFx40_Full_x86_x64.exe", Path.GetFileName(@"G:\dotNetFx40_Full_x86_x64.exe"));


            ftp.Disconnect();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

如何上传文件夹可以通过先建立同名文件夹,遍历文件夹内的文件然后逐个update。递归可以搞定。


0人推荐
随时随地看视频
慕课网APP