欢迎光临
我们一直在努力

一个FTP客户端的C#代码-.NET教程,C#语言

建站超值云服务器,限时71元/月

using system;
using system.net;
using system.io;
using system.text;
using system.net.sockets;

namespace zhangyuk.net.csdn.blog.ftpclient
{
 /// <summary>
 /// ftp client
 /// </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()
  {
   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(“couldnt 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;

   // 切换到目录
   chdir(strremotepath);
  }
   

  /// <summary>
  /// 关闭连接
  /// </summary>
  public void disconnect()
  {
   if( socketcontrol != null )
   {
    sendcommand(“quit”);
   }
   closesocketconnect();
  }

  #endregion

  #region 传输模式

  /// <summary>
  /// 传输模式:二进制类型、ascii类型
  /// </summary>
  public enum transfertype {binary,ascii};

  /// <summary>
  /// 设置传输模式
  /// </summary>
  /// <param name=”tttype”>传输模式</param>
  public void settransfertype(transfertype tttype)
  {
   if(tttype == transfertype.binary)
   {
    sendcommand(“type i”);//binary类型传输
   }
   else
   {
    sendcommand(“type a”);//ascii类型传输
   }
   if (ireplycode != 200)
   {
    throw new ioexception(strreply.substring(4));
   }
   else
   {
    trtype = tttype;
   }
  }

  /// <summary>
  /// 获得传输模式
  /// </summary>
  /// <returns>传输模式</returns>
  public transfertype gettransfertype()
  {
   return trtype;
  }
   
  #endregion

  #region 文件操作
  /// <summary>
  /// 获得文件列表
  /// </summary>
  /// <param name=”strmask”>文件名的匹配字符串</param>
  /// <returns></returns>
  public string[] dir(string strmask)
  {
   // 建立链接
   if(!bconnected)
   {
    connect();
   }

   //建立进行数据连接的socket
   socket socketdata = createdatasocket();
  
   //传送命令
   sendcommand(“nlst ” + 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 += ascii.getstring(buffer, 0, ibytes);
    if(ibytes < buffer.length)
    {
     break;
    }
   }
   char[] seperator = {\n};
   string[] strsfilelist = strmsg.split(seperator);
   socketdata.close();//数据socket关闭时也会有返回码
   if(ireplycode != 226)
   {
    readreply();
    if(ireplycode != 226)
    {
     throw new ioexception(strreply.substring(4));
    }
   }
   return strsfilelist;
  }
   

  /// <summary>
  /// 获取文件大小
  /// </summary>
  /// <param name=”strfilename”>文件名</param>
  /// <returns>文件大小</returns>
  private long getfilesize(string strfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“size ” + path.getfilename(strfilename));
   long lsize=0;
   if(ireplycode == 213)
   {
    lsize = int64.parse(strreply.substring(4));
   }
   else
   {
    throw new ioexception(strreply.substring(4));
   }
   return lsize;
  }

  /// <summary>
  /// 删除
  /// </summary>
  /// <param name=”strfilename”>待删除文件名</param>
  public void delete(string strfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“dele “+strfilename);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   

  /// <summary>
  /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
  /// </summary>
  /// <param name=”stroldfilename”>旧文件名</param>
  /// <param name=”strnewfilename”>新文件名</param>
  public void rename(string stroldfilename,string strnewfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“rnfr “+stroldfilename);
   if(ireplycode != 350)
   {
    throw new ioexception(strreply.substring(4));
   }
   //  如果新文件名与原有文件重名,将覆盖原有文件
   sendcommand(“rnto “+strnewfilename);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
  #endregion

  #region 上传和下载
  /// <summary>
  /// 下载一批文件
  /// </summary>
  /// <param name=”strfilenamemask”>文件名的匹配字符串</param>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  public void get(string strfilenamemask,string strfolder)
  {
   if(!bconnected)
   {
    connect();
   }
   string[] strfiles = dir(strfilenamemask);
   foreach(string strfile in strfiles)
   {
    if(!strfile.equals(“”))//一般来说strfiles的最后一个元素可能是空字符串
    {
     get(strfile,strfolder,strfile);
    }
   }
  }
   

  /// <summary>
  /// 下载一个文件
  /// </summary>
  /// <param name=”strremotefilename”>要下载的文件名</param>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  /// <param name=”strlocalfilename”>保存在本地时的文件名</param>
  public void get(string strremotefilename,string strfolder,string strlocalfilename)
  {
   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));
    }
   }
  }
   

  /// <summary>
  /// 上传一批文件
  /// </summary>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  /// <param name=”strfilenamemask”>文件名匹配字符(可以包含*和?)</param>
  public void put(string strfolder,string strfilenamemask)
  {
   string[] strfiles = directory.getfiles(strfolder,strfilenamemask);
   foreach(string strfile in strfiles)
   {
    //strfile是完整的文件名(包含路径)
    put(strfile);
   }
  }
   

  /// <summary>
  /// 上传一个文件
  /// </summary>
  /// <param name=”strfilename”>本地文件名</param>
  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 目录操作
  /// <summary>
  /// 创建目录
  /// </summary>
  /// <param name=”strdirname”>目录名</param>
  public void mkdir(string strdirname)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“mkd “+strdirname);
   if(ireplycode != 257)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   
 
  /// <summary>
  /// 删除目录
  /// </summary>
  /// <param name=”strdirname”>目录名</param>
  public void rmdir(string strdirname)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“rmd “+strdirname);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   
 
  /// <summary>
  /// 改变目录
  /// </summary>
  /// <param name=”strdirname”>新的工作目录名</param>
  public void chdir(string strdirname)
  {
   if(strdirname.equals(“.”) || strdirname.equals(“”))
   {
    return;
   }
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“cwd “+strdirname);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
   this.strremotepath = strdirname;
  }
   
  #endregion

  #region 内部变量
  /// <summary>
  /// 服务器返回的应答信息(包含应答码)
  /// </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(“cant connect to remote server”);
   }
   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
 }
}

namespace zhangyuk.net.csdn.blog.ftpclient
{
 /// <summary>
 /// ftp client
 /// </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()
  {
   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(“couldnt 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;

   // 切换到目录
   chdir(strremotepath);
  }
   

  /// <summary>
  /// 关闭连接
  /// </summary>
  public void disconnect()
  {
   if( socketcontrol != null )
   {
    sendcommand(“quit”);
   }
   closesocketconnect();
  }

  #endregion

  #region 传输模式

  /// <summary>
  /// 传输模式:二进制类型、ascii类型
  /// </summary>
  public enum transfertype {binary,ascii};

  /// <summary>
  /// 设置传输模式
  /// </summary>
  /// <param name=”tttype”>传输模式</param>
  public void settransfertype(transfertype tttype)
  {
   if(tttype == transfertype.binary)
   {
    sendcommand(“type i”);//binary类型传输
   }
   else
   {
    sendcommand(“type a”);//ascii类型传输
   }
   if (ireplycode != 200)
   {
    throw new ioexception(strreply.substring(4));
   }
   else
   {
    trtype = tttype;
   }
  }

  /// <summary>
  /// 获得传输模式
  /// </summary>
  /// <returns>传输模式</returns>
  public transfertype gettransfertype()
  {
   return trtype;
  }
   
  #endregion

  #region 文件操作
  /// <summary>
  /// 获得文件列表
  /// </summary>
  /// <param name=”strmask”>文件名的匹配字符串</param>
  /// <returns></returns>
  public string[] dir(string strmask)
  {
   // 建立链接
   if(!bconnected)
   {
    connect();
   }

   //建立进行数据连接的socket
   socket socketdata = createdatasocket();
  
   //传送命令
   sendcommand(“nlst ” + 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 += ascii.getstring(buffer, 0, ibytes);
    if(ibytes < buffer.length)
    {
     break;
    }
   }
   char[] seperator = {\n};
   string[] strsfilelist = strmsg.split(seperator);
   socketdata.close();//数据socket关闭时也会有返回码
   if(ireplycode != 226)
   {
    readreply();
    if(ireplycode != 226)
    {
     throw new ioexception(strreply.substring(4));
    }
   }
   return strsfilelist;
  }
   

  /// <summary>
  /// 获取文件大小
  /// </summary>
  /// <param name=”strfilename”>文件名</param>
  /// <returns>文件大小</returns>
  private long getfilesize(string strfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“size ” + path.getfilename(strfilename));
   long lsize=0;
   if(ireplycode == 213)
   {
    lsize = int64.parse(strreply.substring(4));
   }
   else
   {
    throw new ioexception(strreply.substring(4));
   }
   return lsize;
  }

  /// <summary>
  /// 删除
  /// </summary>
  /// <param name=”strfilename”>待删除文件名</param>
  public void delete(string strfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“dele “+strfilename);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   

  /// <summary>
  /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
  /// </summary>
  /// <param name=”stroldfilename”>旧文件名</param>
  /// <param name=”strnewfilename”>新文件名</param>
  public void rename(string stroldfilename,string strnewfilename)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“rnfr “+stroldfilename);
   if(ireplycode != 350)
   {
    throw new ioexception(strreply.substring(4));
   }
   //  如果新文件名与原有文件重名,将覆盖原有文件
   sendcommand(“rnto “+strnewfilename);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
  #endregion

  #region 上传和下载
  /// <summary>
  /// 下载一批文件
  /// </summary>
  /// <param name=”strfilenamemask”>文件名的匹配字符串</param>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  public void get(string strfilenamemask,string strfolder)
  {
   if(!bconnected)
   {
    connect();
   }
   string[] strfiles = dir(strfilenamemask);
   foreach(string strfile in strfiles)
   {
    if(!strfile.equals(“”))//一般来说strfiles的最后一个元素可能是空字符串
    {
     get(strfile,strfolder,strfile);
    }
   }
  }
   

  /// <summary>
  /// 下载一个文件
  /// </summary>
  /// <param name=”strremotefilename”>要下载的文件名</param>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  /// <param name=”strlocalfilename”>保存在本地时的文件名</param>
  public void get(string strremotefilename,string strfolder,string strlocalfilename)
  {
   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));
    }
   }
  }
   

  /// <summary>
  /// 上传一批文件
  /// </summary>
  /// <param name=”strfolder”>本地目录(不得以\结束)</param>
  /// <param name=”strfilenamemask”>文件名匹配字符(可以包含*和?)</param>
  public void put(string strfolder,string strfilenamemask)
  {
   string[] strfiles = directory.getfiles(strfolder,strfilenamemask);
   foreach(string strfile in strfiles)
   {
    //strfile是完整的文件名(包含路径)
    put(strfile);
   }
  }
   

  /// <summary>
  /// 上传一个文件
  /// </summary>
  /// <param name=”strfilename”>本地文件名</param>
  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 目录操作
  /// <summary>
  /// 创建目录
  /// </summary>
  /// <param name=”strdirname”>目录名</param>
  public void mkdir(string strdirname)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“mkd “+strdirname);
   if(ireplycode != 257)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   
 
  /// <summary>
  /// 删除目录
  /// </summary>
  /// <param name=”strdirname”>目录名</param>
  public void rmdir(string strdirname)
  {
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“rmd “+strdirname);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
  }
   
 
  /// <summary>
  /// 改变目录
  /// </summary>
  /// <param name=”strdirname”>新的工作目录名</param>
  public void chdir(string strdirname)
  {
   if(strdirname.equals(“.”) || strdirname.equals(“”))
   {
    return;
   }
   if(!bconnected)
   {
    connect();
   }
   sendcommand(“cwd “+strdirname);
   if(ireplycode != 250)
   {
    throw new ioexception(strreply.substring(4));
   }
   this.strremotepath = strdirname;
  }
   
  #endregion

  #region 内部变量
  /// <summary>
  /// 服务器返回的应答信息(包含应答码)
  /// </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(“cant connect to remote server”);
   }
   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
 }
}

 

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 一个FTP客户端的C#代码-.NET教程,C#语言
分享到: 更多 (0)