【转】WINFORM下FTP客户端的实现

第一种方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Scan
{
    class FtpUpLoadFiles
    { ///   <summary>
        ///   FTPClient   的摘要说明。
        ///   </summary>
        public class FTPClient
        {
            #region   构造函数
            ///   <summary>
            ///   缺省构造函数
            ///   </summary>
            public FTPClient()
            {
                strRemoteHost = " ";
                strRemotePath = " ";
                strRemoteUser = " ";
                strRemotePass = " ";
                strRemotePort = 21;
                bConnected = false;
            }

            ///   <summary>
            ///   构造函数
            ///   </summary>
            ///   <param   name= "remoteHost ">远程主机名 </param>
            ///   <param   name= "remotePath ">远程文件路径 </param>
            ///   <param   name= "remoteUser ">登录服务器用户名 </param>
            ///   <param   name= "remotePass ">登录服务器密码 </param>
            ///   <param   name= "remotePort ">登录服务器端口号 </param>
            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   登陆属性
            ///   <summary>
            ///   FTP服务器IP地址
            ///   </summary>
            private string strRemoteHost;

            public string RemoteHost
            {
                get
                {
                    return strRemoteHost;
                }
                set
                {
                    strRemoteHost = value;
                }
            }
            ///   <summary>
            ///   FTP服务器端口
            ///   </summary>
            private int strRemotePort;
            public int RemotePort
            {
                get
                {
                    return strRemotePort;
                }
                set
                {
                    strRemotePort = value;
                }
            }
            ///   <summary>
            ///   当前服务器目录
            ///   </summary>
            private string strRemotePath;
            public string RemotePath
            {
                get
                {
                    return strRemotePath;
                }
                set
                {
                    strRemotePath = value;
                }
            }
            ///   <summary>
            ///   登录用户账号
            ///   </summary>
            private string strRemoteUser;
            public string RemoteUser
            {
                set
                {
                    strRemoteUser = value;
                }
            }
            ///   <summary>
            ///   用户登录密码
            ///   </summary>
            private string strRemotePass;
            public string RemotePass
            {
                set
                {
                    strRemotePass = value;
                }
            }     ///   <summary>
            ///   是否登录
            ///   </summary>
            private Boolean bConnected;

            public bool Connected
            {
                get
                {
                    return bConnected;
                }
            }
            #endregion


            #region   连接
            ///   <summary>
            ///   建立连接  
            ///   </summary>
            public void Connect()
            {
                Socket 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("不能连接到远程服务器!");
                }
                //   获取应答码
                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= "strFileNameMask "> 文件名的匹配字符串 </param>
            ///   <param   name= "strFolder "> 本地目录(不得以\结束) </param>
            ///   <returns> 返回true成功 </returns>
            public bool Get(string strFileNameMask, string strFolder)
            {
                try
                {
                    if (!bConnected)
                    {
                        Connect();
                    }
                    string[] strFiles = Dir(strFileNameMask);
                    foreach (string strFile in strFiles)
                    {
                        if (!strFile.Equals(" "))//一般来说strFiles的最后一个元素可能是空字符串
                        {
                            if (!Get(strFile, strFolder, strFile)) return false;
                        }
                    }
                    return true;
                }
                catch { return false; }
            }


            ///   <summary>
            ///   下载一个文件
            ///   </summary>
            ///   <param   name= "strRemoteFileName "> 要下载的文件名 </param>
            ///   <param   name= "strFolder "> 本地目录(不得以\结束) </param>
            ///   <param   name= "strLocalFileName "> 保存在本地时的文件名 </param>
            ///   <returns> 返回true成功 </returns>
            public bool Get(string strRemoteFileName, string strFolder, string strLocalFileName)
            {
                try
                {
                    if (!bConnected)
                    {
                        Connect();
                    }
                    long fsSize = 0;
                    FileStream fs;
                    SetTransferType(TransferType.Binary);
                    if (strLocalFileName.Equals(" "))
                    {
                        strLocalFileName = strRemoteFileName;
                    }

                    if (File.Exists(strFolder + "\\ " + strLocalFileName))
                    {
                        fs = File.OpenWrite(strFolder + "\\ " + strLocalFileName);
                        fsSize = fs.Length;
                        fs.Seek(fsSize, SeekOrigin.Current);
                    }
                    else
                    {
                        fs = new FileStream(strFolder + "\\ " + strLocalFileName, FileMode.Create);
                        fsSize = 0;
                    }


                    Socket socketData = CreateDataSocket();
                    SendCommand("RETR   " + strRemoteFileName);

                    //125数据连接已打开,准备传送        
                    //150文件状态良好,打开数据连接`
                    //226关闭数据连接,请求的文件x作成功
                    //250请求的文件x作完成
                    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);
                        fs.Write(buffer, 0, iBytes);
                        if (iBytes <= 0)
                        {
                            break;
                        }
                    }
                    fs.Close();


                    if (socketData.Connected)
                    {
                        socketData.Close();
                    }
                    //226关闭数据连接,请求的文件x作成功
                    //250请求的文件x作完成
                    if (!(iReplyCode == 226 || iReplyCode == 250))
                    {
                        ReadReply();
                        if (!(iReplyCode == 226 || iReplyCode == 250))
                        {
                            throw new IOException(strReply.Substring(4));
                        }
                    }
                    return true;
                }
                catch { return false; }
            }

            ///   <summary>
            ///   上传一批文件
            ///   </summary>
            ///   <param   name= "strFolder "> 本地目录(不得以\结束) </param>
            ///   <param   name= "strFileNameMask "> 文件名匹配字符(可以包含*和?) </param>
            ///   <returns> 返回true成功 </returns>
            public bool Put(string strFolder, string strFileNameMask)
            {
                try
                {
                    string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask);
                    foreach (string strFile in strFiles)
                    {
                        //strFile是完整的文件名(包含路径)
                        if (!Put(strFile)) return false;
                    }
                    return true;
                }
                catch { return false; }
            }

            ///   <summary>
            ///   上传一个文件
            ///   </summary>
            ///   <param   name= "strFileName "> 本地文件名 </param>
            ///   <returns> 返回true成功 </returns>
            public bool Put(string strFileName)
            {
                try
                {
                    if (!bConnected)
                    {
                        Connect();
                    }
                    //FileStream   input;
                    //long   readSize;
                    Socket socketData = CreateDataSocket();
                    SendCommand("STOR   " + Path.GetFileName(strFileName));
                    //125数据连接已打开,准备传送        
                    //150文件状态良好,打开数据连接`
                    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();
                    }
                    //226关闭数据连接,请求的文件x作成功
                    //250请求的文件x作完成
                    if (!(iReplyCode == 226 || iReplyCode == 250))
                    {
                        ReadReply();
                        if (!(iReplyCode == 226 || iReplyCode == 250))
                        {
                            throw new IOException(strReply.Substring(4));
                        }
                    }
                    return true;
                }
                catch { return false; }
            }

            #endregion
             #region   内部变量
                ///   <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;
                byte[]   buffer   =   new   byte[BLOCK_SIZE];
                ///   <summary>
                ///   编码方式
                ///   </summary>
                Encoding   ASCII   =   Encoding.ASCII;
                #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( "不能链接到远程服务器! ");
                        }
                        return   s;
                }


                ///   <summary>
                ///   关闭socket连接(用于登录以前)
                ///   </summary>
                private   void   CloseSocketConnect()
                {
                        if   (socketControl   !=   null)
                        {
                                socketControl.Close();
                                socketControl   =   null;
                        }
                        bConnected   =   false;
                }

                ///   <summary>
                ///   读取Socket返回的所有字符串
                ///   </summary>
                ///   <returns> 包含应答码的字符串行 </returns>
                private   string   ReadLine()
                {
                        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];
                                //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,
                                //但也会分配为空字符串给后面(也是最后一个)字符串数组,
                                //所以最后一个mess是没用的空字符串
                                //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格
                        }
                        else
                        {
                                strMsg   =   mess[0];
                        }
                        if   (!strMsg.Substring(3,   1).Equals( "   "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
                        {
                                return   ReadLine();
                        }
                        return   strMsg;
                }
                ///   <summary>
                ///   发送命令并获取应答码和最后一行应答字符串
                ///   </summary>
                ///   <param   name= "strCommand "> 命令 </param>
                private   void   SendCommand(String   strCommand)
                {
                        Byte[]   cmdBytes   =
                          Encoding.ASCII.GetBytes((strCommand   +   "\r\n").ToCharArray());
                        socketControl.Send(cmdBytes,   cmdBytes.Length,   0);
                        ReadReply();
                }
                #endregion

        }
    }
}

第二种方法:

//ftp方式上传
  public static int UploadFtp(string filePath, string filename, string ftpServerIP, string ftpUserID, string ftpPassword)
  {
   
  FileInfo fileInf = new FileInfo(filePath + "\\" + filename);
  string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
  FtpWebRequest reqFTP;
   

  // Create FtpWebRequest object from the Uri provided
  reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
  try
  {

  // Provide the WebPermission Credintials
  reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

  // By default KeepAlive is true, where the control connection is not closed
  // after a command is executed.
  reqFTP.KeepAlive = false;

  // Specify the command to be executed.
  reqFTP.Method = WebRequestMethods.Ftp.UploadFile;

  // Specify the data transfer type.
  reqFTP.UseBinary = true;

  // Notify the server about the size of the uploaded file
  reqFTP.ContentLength = fileInf.Length;

  // The buffer size is set to 2kb
  int buffLength = 2048;
  byte[] buff = new byte[buffLength];
  int contentLen;

  // Opens a file stream (System.IO.FileStream) to read the file to be uploaded
  //FileStream fs = fileInf.OpenRead();
  FileStream fs = fileInf.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);


  // Stream to which the file to be upload is written
  Stream strm = reqFTP.GetRequestStream();

  // Read from the file stream 2kb at a time
  contentLen = fs.Read(buff, 0, buffLength);

  // Till Stream content ends
  while (contentLen != 0)
  {
  // Write Content from the file stream to the FTP Upload Stream
  strm.Write(buff, 0, contentLen);
  contentLen = fs.Read(buff, 0, buffLength);
  }

  // Close the file stream and the Request Stream
  strm.Close();
  fs.Close();
  return 0;
  }
  catch (Exception ex)
  {
  reqFTP.Abort();
  Logging.WriteError(ex.Message + ex.StackTrace);
  return -2;
  }
  }
  //ftp方式下载
  public static int DownloadFtp(string filePath, string fileName, string ftpServerIP, string ftpUserID, string ftpPassword)
  {
  FtpWebRequest reqFTP;
  try
  {
  //filePath = <<The full path where the file is to be created.>>, 
  //fileName = <<Name of the file to be created(Need not be the name of the file on FTP server).>>
  FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);

  reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileName));
  reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
  reqFTP.UseBinary = true;
  reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
  FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
  Stream ftpStream = response.GetResponseStream();
  long cl = response.ContentLength;
  int bufferSize = 2048;
  int readCount;
  byte[] buffer = new byte[bufferSize];

  readCount = ftpStream.Read(buffer, 0, bufferSize);
  while (readCount > 0)
  {
  outputStream.Write(buffer, 0, readCount);
  readCount = ftpStream.Read(buffer, 0, bufferSize);
  }

  ftpStream.Close();
  outputStream.Close();
  response.Close();
  return 0;
  }
  catch (Exception ex)
  {
  Logging.WriteError(ex.Message + ex.StackTrace);
  return -2;
  }
  }

原文地址:https://www.cnblogs.com/vic_lu/p/2063228.html