使用嵌套字用FTP协议进行文件上传下载!

 以下代码使用C#完成!完成。

  
using System;
using System.Net.Sockets;

/// <summary>
/// Ftp 的摘要说明。
/// </summary>
public class Ftp
{
  public Ftp()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
  string _ser;
  public string Server
  {
   set{ _ser=value;}
   get{return _ser;}
  }
  string _port;
  public string Port
  {
   set{_port=value;}
   get{return _port;}
  }
  string _user;
  public string User
  {
   set{ _user=value;}
   get{return _user;}
  }
  string _pws;
  public string Password
  {
   set{ _pws=value;}
   get{return _pws;}
  }
  bool  _IsLog;
  public bool IsLogined
  {
   set{ _IsLog=value;}
   get{return _IsLog;}
  }
  int  _MsgID;
  public int MsgID
  {
   set{ _MsgID=value;}
   get{return _MsgID;}
  }
  System.Windows.Forms.Label _infx=new System.Windows.Forms.Label() ;
  public System.Windows.Forms.Label InfsShow
  {
   set{_infx=value;}
   get{return _infx;}
  }
  System.Windows.Forms.ListBox  _infs=new System.Windows.Forms.ListBox();
  public System.Windows.Forms.ListBox  InfsList
  {
   set{_infs=value;}
   get{return _infs;}
  }
  System.Windows.Forms.ProgressBar   _pb=new  System.Windows.Forms.ProgressBar() ;
  public System.Windows.Forms.ProgressBar  Progress
  {
   set{_pb=value;}
   get{return _pb;}
  }
  public string NowInf;
  System.Net.Sockets.TcpClient tcFtp;
  NetworkStream Stm;
  public bool Login()
  {
   try
   {
    SetInf("正在连接服务器...");
    tcFtp=new TcpClient(_ser, System.Convert.ToInt32(_port));//连接服务器
    Stm= tcFtp.GetStream();//获取网络流
    byte[] data=new byte[255];
    int bytes;
    SetInf("等待服务器就绪!");
    bytes=Stm.Read(data,0,data.Length);
    string msg=System.Text.Encoding.ASCII.GetString(data,0,bytes);//读取登录成功的消息
    if (msg.Substring(0,3)=="220")
    {
     SetInf(msg);
     if (DoCmd("USER " + _user+" ","331"))
     {
      if (DoCmd("PASS " + _pws,"230"))
      {
      
       SetInf("服务器就绪!");
       this.IsLogined=true;
       return true;
      }  
      SetInf("密码错误!",230);
      return false;
     }
     SetInf("用户名错误",331);
     return false;
    }
    else
    {
     SetInf("服务器没有正确响应!",220);
     return false;
    }

    
   }
   catch (System.Exception ex)
   {
    NowInf=ex.Message ;
    _infx.Text=NowInf;
    return false;
   }

    

  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="cmd"></param>
  /// <param name="wait">匹配前面的字符就可以了</param>
  /// <returns></returns>
  private bool DoCmd(string cmd,string wait)
  {
   string msg=DoCommand(cmd);
    SetInf(msg);
   if (msg.IndexOf("/r/n")>=0)
   {
    string xx=msg.Substring(msg.IndexOf("/r/n")) ;

    msg=(xx=="/r/n"?msg:xx);
    msg=msg.Replace("/r/n","");
   }
   msg+="/r/n";
   return (msg.Substring(0,wait.Length).ToLower()==wait.ToLower() );//如果msg的前部分是wait,则返回成功.
  }
  private bool RetOk(string s1,string s2)
  {
   string msg=s1;
   if (msg.IndexOf("/r/n")>=0)
   {
    string xx=msg.Substring(msg.IndexOf("/r/n")) ;
    msg=(xx=="/r/n"?msg:xx);
       msg=msg.Replace("/r/n","");
   }
   s1=msg+"/r/n";
   return (s1.Substring(0,s2.Length).ToLower()==s2.ToLower() );//如果msg的前部分是wait,则返回成功.
  }
  private string DoCommand(string cmd)
  {
   string msg=cmd;//+System.Text.Encoding.ASCII.GetString(vbnull);
   byte[] data=System.Text.Encoding.ASCII.GetBytes(msg+"/r/n");
   Stm.Write(data,0,data.Length);
            System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();

   data=new byte[255];
   int bytes;
   while(Stm.DataAvailable==false)  
   {
    System.Windows.Forms.Application.DoEvents() ;
    NowInf="正在等待服务器响应!";
   }
   bytes=Stm.Read(data,0,data.Length);
   msg=System.Text.Encoding.ASCII.GetString(data,0,bytes);
   return msg;
  }

  private void SetInf(string msg)
  {
   if( msg.IndexOf("/r/n")>=0)
   {
    msg=msg.Substring(0,msg.LastIndexOf("/r/n")-"/r/n".Length );
    msg+=" "+ System.DateTime.Now.TimeOfDay.ToString();
   }
   NowInf=msg;
   _infx.Text=NowInf;
   _infs.Items.AddRange(msg.Split("/r/n".ToCharArray()));
   System.Windows.Forms.Application.DoEvents();
   _infs.SelectedIndex=_infs.Items.Count-1;
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
  }

  private void SetInf(string msg,int msgid)
  {
   SetInf(msg);
   _MsgID=msgid;
  }

  private string GetMsg()
  {
   string msg;
   byte[] data=new byte[1024];
   int bytes;
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   System.Windows.Forms.Application.DoEvents();
   while(Stm.DataAvailable==false)//如果没有信息可读,等待服务器响应.  
   {
    
    System.Windows.Forms.Application.DoEvents() ;
   }
   bytes=Stm.Read(data,0,data.Length);//读取数据
   msg=System.Text.Encoding.ASCII.GetString(data,0,bytes);//转换为字符
   int rn= msg.IndexOf("/r/n",0);//查找换行符号
   if (rn>0)
   {
    string mg=msg.Substring(rn);//这里是为了防止传输来多行数据,我试图加大缓冲,也是这样.
    if( mg.Length>2)//在这里处理如同226这样消息.
    {                 //前面一次返回接受了一部分,第二次接受到了前面的一部分,在这里用来分开他们
     mg=mg.Substring(2);
     msg=mg;
    }
   }
   SetInf(msg);
   return msg;
  }
  /// <summary>
  /// 注销登录
  /// </summary>
  /// <returns>成功时返回真</returns>
  public bool Logout()
  {
   this.IsLogined=false;
   bool ok=DoCmd("QUIT","221");
   SetInf("已断开服务器!",221);
   return ok;
  
  }
  public bool SetCurDir(string Path)
  {

    
   if (DoCmd("CWD "+Path,"250")==false)//"" is current directory.
   {
    SetInf("确认当前目录失败!",257);
    return false;
   }
   if (DoCmd("PWD "+Path,"257")==false)//"" is current directory.
   {
    SetInf("确认当前目录失败!",257);
    return false;
   }
   return true;
  }
  public string  GetCurDir()
  {

    
   string msg=DoCommand("PWD");
   string[] st=msg.Split((char)34);
   return st[1];
  }

  public bool Delete(string FileName)
  {
   return DoCmd("DELE "+FileName,"250");
  }

  /// <summary>
  /// 上传文件
  /// </summary>
  /// <param name="FileName">要上传的本地文件</param>
  /// <param name="SvrPath">服务器目标路径.</param>
  /// <returns>传输成功返回真.</returns>
  public bool UploadFile(string FileName)
  {
   _pb.Value=5;
   if (this.IsLogined==false)
   {
    SetInf("没有连接到服务器或没有登录!");
    return false;
   }
   if (DoCmd("TYPE I","200")==false)//Type set to I.
   {
    SetInf("执行Type i失败!",200);
    return false;  
   }
   _pb.Value=10;
   string[] pt=FileName.Split("//".ToCharArray());
   string filename=pt[pt.Length-1] ;//SvrPath+"/"+pt[pt.Length-1] ;
   string tmp1=DoCommand("SIZE "+ filename);
   SetInf(tmp1);
   if (RetOk(tmp1,"550")!=true)//50 /bbs/Dv_ForumNews/广告.txt: No such file.
   {
    if (RetOk(tmp1,"501")!=true)
    {
     SetInf("文件已存在!",550);
     return false;  
    }
    else
    {
     SetInf("文件名为空,请指定文件名!",501);
     return false;  
    }

   }
   _pb.Value=15;
   if (DoCmd("MODE S" ,"200")==false)//Type set to I.
   {
    SetInf("模式设置失败!");
    //return false;  
   }
   /////获取传输文件的ip和段口
   string tmp2 =DoCommand("PASV");
   SetInf(tmp2);
   if (RetOk(tmp2,"227")==false)//Type set to I.
   {
    SetInf("服务器没有返回227,无法知道端口,也无法开始传输文件!",227);
    return false;  
   }
   string[] ips=GetIP( tmp2);
   ///////////////////
   TcpClient tcm;
   try
   {
    _pb.Value=20;
    SetInf("正在连接文件传输服务器!");
    tcm=new TcpClient(ips[0],System.Convert.ToInt32(ips[1]));//连接传输服务器.
   }
   catch (System.Exception ex1)
   {
    SetInf("连接文件传输服务器时出错:IP地址:"+ips[0]+"端口:" + ips[1]+"  相关信息:" + ex1.Message );
    return false;
   }
   if (DoCmd("STOR "+ filename,"150")==false)//发送传输文件的指令.返回应该是150,否则出错
   {
    SetInf("开始传输文件的指令服务器响应的不是150,不知道服务器是不是准备接受文件!",150);
    return false;  
   }
   //读取文件///////////////////////
   SetInf("正在读取文件,准备传输...");
   System.IO.FileStream fs;
   byte[] fbins;
   try
   {
    _pb.Value=25;
    fs=new System.IO.FileStream(FileName,System.IO.FileMode.Open,System.IO.FileAccess.Read);
    fbins=new byte[fs.Length] ;
    fs.Read(fbins,0,System.Convert.ToInt32(fs.Length));
   }
   catch( System.Exception ex2)
   {
    SetInf("文件读取失败,失败原因:"+ex2.Message);
    return false;
   }
   _pb.Value=35;
   /////////////////////////////////////////////////////
   NetworkStream tmx=tcm.GetStream();//获得流
   SetInf("正在向网络数据流中写入数据...");
   _pb.Value=45;
   tmx.Write(fbins,0,fbins.Length);//写入信息
   tmx=null;
   tcm.Close();
   _pb.Value=55;
   if (RetOk(GetMsg(),"226")==false)//一般226信息为两次 ,本次是说明磁盘目前可用大小已经使用大小
   {

   }
  
   string tmp3;
   _pb.Value=65;
   tmp3=DoCommand("SIZE "+ filename);//获取大小.
   SetInf(tmp3);
   _pb.Value=75;
   if (RetOk(tmp3,"213"))//返回大小
   {
    SetInf("正在核对文件大小");
    int ln=System.Convert.ToInt32(tmp3.Substring(4));//得到远程文件的大小
    _pb.Value=89;
    if( ln==fbins.Length)//如果大小相同.说明完整传输.
    {
     SetInf("文件传输成功!",0);
     return true;
    }
    SetInf("文件传输后文件大小不一致!",213);
    return false;
   }
   _pb.Value=100;
   SetInf("文件传输成功,但确认文件大小时服务器响应的不是213!因此无法保证数据传输是否正确!",213);
  
   return false;
  }

  /// <summary>
  /// 从消息里提取用于传输文件的服务器地址和端口
  /// </summary>
  /// <param name="Inf">消息</param>
  /// <returns>数组,0为ip地址,1为端口.</returns>
  private string[] GetIP(string Inf)
  {
   string[] rt=new string[2];
   if (Inf.IndexOf("(")>0 )
   {
    string ips=Inf.Substring( Inf.IndexOf("(")+1);
    ips=ips.Substring(0,ips.IndexOf(")"));
    string[] ip=ips.Split(",".ToCharArray());
    rt[0]=ip[0]+"."+ip[1]+"."+ip[2]+"."+ip[3];//前面4组byte是ip地址.
    int x1=System.Convert.ToInt16(ip[4]);//ip地址
    int x2=System.Convert.ToInt16(ip[5]);//端口
    int rtx=x1*256+x2;//计算端口.消息里后两组byte是端口,前者乘256加上后者就是服务器给你的端口.
    rt[1]=rtx.ToString();
   }
   return rt;
  
  }
  public bool DownloadFile(string SvrFileName,string SaveToFileName)
  {
   string FileName=SvrFileName;
   if (this.IsLogined==false)
   {
    SetInf("没有连接到服务器或没有登录!");
    return false;
   }
   _pb.Value=5;
   DoCmd("NOOP","200");
  
   if (DoCmd("TYPE I","200")==false)//Type set to I.
   {
    SetInf("执行Type i失败!",200);
    return false;  
   }
   _pb.Value=10;
   DoCmd("NOOP","200");

   _pb.Value=25;
   if (DoCmd("MODE S" ,"200")==false)//Type set to I.
   {
    SetInf("模式设置失败!",200);
    //return false;  
   }
   /////获取传输文件的ip和段口
   DoCmd("NOOP","200");
   _pb.Value=34;
   string tmp2 =DoCommand("PASV");
   SetInf(tmp2);
    _pb.Value=40;;
   if (RetOk(tmp2,"227")==false)//Type set to I.
   {
    SetInf("服务器没有返回227,无法知道端口,也无法开始传输文件!",227);
    return false;  
   }
   string[] ips=GetIP( tmp2);
   TcpClient tcm;
   try
   {
    _pb.Value=50;
    SetInf("正在连接文件传输服务器!");
    tcm=new TcpClient(ips[0],System.Convert.ToInt32(ips[1]));//连接传输服务器.
   }
   catch (System.Exception ex1)
   {
    SetInf("连接文件传输服务器时出错:IP地址:"+ips[0]+"端口:" + ips[1]+"  相关信息:" + ex1.Message );
    return false;
   }
   _pb.Value=55;
   DoCmd("NOOP","200");
   string inf=DoCommand("RETR "+ FileName);
   if (inf.IndexOf("150")==-1)
   {
    SetInf(inf);
    return false;
   }

    _pb.Value=60;
   SetInf("正在准备接收文件...");
   System.IO.FileStream fs;
    
   try
   {
    fs=new System.IO.FileStream(SaveToFileName,System.IO.FileMode.OpenOrCreate ,System.IO.FileAccess.ReadWrite );
   }
   catch( System.Exception ex2)
   {
    SetInf("文件创建或打开失败,失败原因:"+ex2.Message);
    return false;
   }
   /////////////////////////////////////////////////////
   ///
   NetworkStream tmx=tcm.GetStream();//获得流
   _pb.Value=70;
   SetInf("正在接收文件...");
   int i=0;
   int c=0;
   do
   {
  
    byte[] dats=new byte[10240];
    i=tmx.Read(dats,0,dats.Length);
    c+=i;
    System.Windows.Forms.Application.DoEvents();
    System.Windows.Forms.Application.DoEvents();
    System.Windows.Forms.Application.DoEvents();
    fs.Write(dats,0,i);
    System.Windows.Forms.Application.DoEvents();
    System.Windows.Forms.Application.DoEvents();
    System.Windows.Forms.Application.DoEvents();
    this.InfsShow.Text=c+"字节已复制.";
   }
   while (i>0 );
   c=0;
   this.InfsShow.Text="正在保存文件!";
   fs.Close();
   tmx=null;
   tcm.Close();
   DoCmd("NOOP","200");
   this.InfsShow.Text="";
   return true;
  }
}

时间: 2024-10-30 22:56:22

使用嵌套字用FTP协议进行文件上传下载!的相关文章

Java实现FTP批量大文件上传下载篇1_java

本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比较通用且功能较强的j-ftp类库,对一些比较常见的功能如进度条.断点续传.内外网的映射.在Applet中回调JavaScript函数等问题进行详细的阐述及代码实现,希望通过此文起到一个抛砖引玉的作用. 一.引子 笔者在实施一个项目过程中出现了一种基于Web的文件上传下载需求.在全省(或全国)各地的用

使用Android的OkHttp包实现基于HTTP协议的文件上传下载_Android

OkHttp的HTTP连接基础虽然在使用 OkHttp 发送 HTTP 请求时只需要提供 URL 即可,OkHttp 在实现中需要综合考虑 3 种不同的要素来确定与 HTTP 服务器之间实际建立的 HTTP 连接.这样做的目的是为了达到最佳的性能. 首先第一个考虑的要素是 URL 本身.URL 给出了要访问的资源的路径.比如 URL http://www.baidu.com 所对应的是百度首页的 HTTP 文档.在 URL 中比较重要的部分是访问时使用的模式,即 HTTP 还是 HTTPS.这会

EDI中JAVA通过FTP工具实现文件上传下载实例_java

最近接手一个EDI项目,收获颇多.其实我在第一家公司是接触过EDI的,当初我们用EDI主要实现了订单数据传输,客户向我们下达采购订单,通过VPN及FTP工具将采购订单以约定的报文形式放到指定的文件服务器中,然后我们EDI系统会定时去文件服务器中获取报文,最后解析并生成我们的销售订单.这些年过去了,我仍记着当初用的最多的是EDI850.EDI855.  一.首先介绍一下EDI的概念 Electronic data interchange,电子数据交换. EDI其实就是把原来纸质的订单/发货通知等业

使用Android的OkHttp包实现基于HTTP协议的文件上传下载

OkHttp的HTTP连接基础 虽然在使用 OkHttp 发送 HTTP 请求时只需要提供 URL 即可,OkHttp 在实现中需要综合考虑 3 种不同的要素来确定与 HTTP 服务器之间实际建立的 HTTP 连接.这样做的目的是为了达到最佳的性能. 首先第一个考虑的要素是 URL 本身.URL 给出了要访问的资源的路径.比如 URL http://www.baidu.com 所对应的是百度首页的 HTTP 文档.在 URL 中比较重要的部分是访问时使用的模式,即 HTTP 还是 HTTPS.这

Java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题_java

废话不多说了,直接给大家贴代码了,具体代码如下所示: //文件上传 public static boolean uploadToFTP(String url,int port,String username,String password,String path,String filename,InputStream input) { boolean success=false; FTPClient ftp=new FTPClient();//org.apache.commons.net.ftp

新人求助!C#如何实现winform C/S架构下 局域网内文件上传下载

问题描述 C#怎么实现winformC/S架构下局域网内文件上传下载啊,局域网内一台电脑用作服务器,其余电脑用作客户端,如何实现啊,各位大神帮忙啊 解决方案 解决方案二:最简单的是使用ftp协议,服务器端不用写,用iis配置下,客户端用ftpclienthttp://blog.csdn.net/yafzhp/article/details/5896643解决方案三:用FTP下载协议可以使用winfrom做解决方案四:谢谢各位,先研究研究解决方案五:http上传下载也很方便解决方案六:FTP服务器

利用ssh实现服务器文件上传下载_java

通过ssh实现服务器文件上传下载 写在前面的话 之前记录过一篇使用apache的FTP开源组件实现服务器文件上传下载的方法,但是后来发现在删除的时候会有些权限问题,导致无法删除服务器上的文件.虽然在Windows上使用FileZilla Server设置读写权限后没问题,但是在服务器端还是有些不好用. 因为自己需要实现资源管理功能,除了单文件的FastDFS存储之外,一些特定资源的存储还是打算暂时存放服务器上,项目组同事说后面不会专门在服务器上开FTP服务,于是改成了sftp方式进行操作. 这个

JavaWeb文件上传下载功能示例解析_java

在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 1. 上传简单示例 Jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"&g

Java FTPClient实现文件上传下载_java

在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件.所用到的jar包有:  commons-net-1.4.1.jar  jakarta-oro.jar  一.上传文件 文件上传源代码 /** * Description: 向FTP服务器上传文件 * @Version1.0 * @param url FTP服务器hostname * @param