c# 操作ftp

2021-02-20 08:16

阅读:399

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Net.Sockets;

using System.IO;

using System.Threading;

using System.Net;

 

namespace Hawk

{

    class DoFtp_socket

    {

        public class FTPClient

        {

            public static object obj = new object();

 

            #region 构造函数

            ///

            /// 缺省构造函数

            ///

            public FTPClient()

            {

                strRemoteHost = "";

                strRemotePath = "";

                strRemoteUser = "";

                strRemotePass = "";

                strRemotePort = 0;

                bConnected = false;

            }

 

            ///

            /// 构造函数

            ///

            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;

 

            ///

            /// 服务器返回的应答信息(包含应答码)

            ///

            private string strMsg;

            ///

            /// 服务器返回的应答信息(包含应答码)

            ///

            private string strReply;

            ///

            /// 服务器返回的应答码

            ///

            private int iReplyCode;

            ///

            /// 进行控制连接的socket

            ///

            private Socket socketControl;

            ///

            /// 传输模式

            ///

            private TransferType trType;

            ///

            /// 接收和发送数据的缓冲区

            ///

            private static int BLOCK_SIZE = 512;

            ///

            /// 编码方式

            ///

            Encoding ASCII = Encoding.ASCII;

            ///

            /// 字节数组

            ///

            Byte[] buffer = new Byte[BLOCK_SIZE];

            #endregion

 

            #region 属性

            ///

            /// FTP服务器IP地址

            ///

            public string RemoteHost

            {

                get

                {

                    return strRemoteHost;

                }

                set

                {

                    strRemoteHost = value;

                }

            }

 

            ///

            /// FTP服务器端口

            ///

            public int RemotePort

            {

                get

                {

                    return strRemotePort;

                }

                set

                {

                    strRemotePort = value;

                }

            }

 

            ///

            /// 当前服务器目录

            ///

            public string RemotePath

            {

                get

                {

                    return strRemotePath;

                }

                set

                {

                    strRemotePath = value;

                }

            }

 

            ///

            /// 登录用户账号

            ///

            public string RemoteUser

            {

                set

                {

                    strRemoteUser = value;

                }

            }

 

            ///

            /// 用户登录密码

            ///

            public string RemotePass

            {

                set

                {

                    strRemotePass = value;

                }

            }

 

            ///

            /// 是否登录

            ///

            public bool Connected

            {

                get

                {

                    return bConnected;

                }

            }

            #endregion

 

            #region 链接

            ///

            /// 建立连接

            ///

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

            }

 

            ///

            /// 关闭连接

            ///

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

                    {

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

                    }

                }

            }

 

            ///

            /// 获取文件大小

            ///

            /// 文件名

            /// 文件大小

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

                    {

 

                        break;

                    }

                }

                byte[] bt = ms.GetBuffer();

                strResult = System.Text.Encoding.ASCII.GetString(bt);

                ms.Close();

                return strResult;

            }

 

            ///

            /// 删除

            ///

            /// 待删除文件名

            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的最后一个元素可能是空字符串

                    {

                        Get(strFile, strFolder, strFile);

                    }

                }

            }

 

            ///

            /// 下载一个文件sdsd

            ///

            /// 要下载的文件名

            /// 本地目录(不得以\结束)

            /// 保存在本地时的文件名

            public void Get(string strRemoteFileName, string strFolder, string strLocalFileName)

            {

                Socket socketData = CreateDataSocket();

                try

                {

                    if (!bConnected)

                    {

                        Connect();

                    }

                    SetTransferType(TransferType.Binary);

                    if (strLocalFileName.Equals(""))

                    {

                        strLocalFileName = strRemoteFileName;

                    }

                    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

                        {

                            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;

                }

            }

 

            ///

            /// 下载一个文件

            ///

            /// 要下载的文件名

            /// 本地目录(不得以\结束)

            /// 保存在本地时的文件名

            public void GetNoBinary(string strRemoteFileName, string strFolder, string strLocalFileName)

            {

                if (!bConnected)

                {

                    Connect();

                }

 

                if (strLocalFileName.Equals(""))

                {

                    strLocalFileName = strRemoteFileName;

                }

                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

                    {

                        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)

                {

                    Put(strFile);

                }

            }

 

            ///

            /// 上传一个文件

            ///

            /// 本地文件名

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

                    }

                }

            }

 

 

            ///

            /// 上传一个文件

            ///

            /// 本地文件名

            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 目录操作

            ///

            /// 创建目录

            ///

            /// 目录名

            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 内部函数

            ///

            /// 将一行应答字符串记录在strReply和strMsg,应答码记录在iReplyCode

            ///

            private void ReadReply()

            {

                strMsg = "";

                strReply = ReadLine();

                iReplyCode = Int32.Parse(strReply.Substring(0, 3));

            }

 

            ///

            /// 建立进行数据连接的socket

            ///

            /// 数据连接socket

            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

                {

                    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]

                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;

            }

 

            ///

            /// 关闭socket连接(用于登录以前)

            ///

            private void CloseSocketConnect()

            {

                lock (obj)

                {

                    if (socketControl != null)

                    {

                        socketControl.Close();

                        socketControl = null;

                    }

                    bConnected = false;

                }

            }

 

            ///

            /// 读取Socket返回的所有字符串

            ///

            /// 包含应答码的字符串行

            private string ReadLine()

            {

                lock (obj)

                {

                    while (true)

                    {

                        int iBytes = socketControl.Receive(buffer, buffer.Length, 0);

                        strMsg += ASCII.GetString(buffer, 0, iBytes);

                        if (iBytes

                        {

                            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;

            }

 

            ///

            /// 发送命令并获取应答码和最后一行应答字符串

            ///

            /// 命令

            public void SendCommand(String strCommand)

            {

                lock (obj)

                {

                    Byte[] cmdBytes = Encoding.ASCII.GetBytes((strCommand + "\r\n").ToCharArray());

                    socketControl.Send(cmdBytes, cmdBytes.Length, 0);

                    Thread.Sleep(500);

                    ReadReply();

                }

            }

            #endregion

        }

    }

}

 


评论


亲,登录后才可以留言!