小洪維尼 发表于 2015-5-27 13:26:10

FTP断点续传的

Code
/*
*
* 功能说明:客户端FTP的操作类
*
* FTP Command:
*
* 1.用户名.(USER)
* 2.口令(PASS)
* 3.认证(ACCT)
* 4.改变工作目录.(CWD)
* 5.回到上一层目录..(CDUP)
* 6.结构加载..(SMNT)
* 7.重新登录..(REIN)
* 8.退出登录..(QUIT)
* 9.数据端口..(PORT)
* 10.被动..(PASV)
* 11.类型..(TYPE)
* 12.文件结构.(STRU)
* 13.传输模式.(MODE)
* 14.获得文件.(RETR)
* 15.上传文件.(STOR)
* 16.唯一保存.(STOU)
* 17.附加..(APPE)
* 18.分配..(ALLO)
* 19.重新开始.(REST)
* 20.重命名(RNFR)
* 21.重命名为.(RNTO)
* 22.放弃..(ABOR)
* 23.删除..(DELE)
* 24.删除目录.(RMD)
* 25.创建目录.(MKD)
* 26.打印工作目录(PWD)
* 27.列目录(LIST)
* 28.站点参数.(SITE)
* 29.系统..(SYST)
* 30.状态..(STAT)
* 31.帮助..(HELP)
* 32.等待..(NOOP)
* */


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


///
/// FtpUtil 的摘要说明。
///
public class FtpUtil
{
private Int32_RemotePort;
private String_RemoteHost;
private String_RemoteAccounts;
private String_RemotePassword;
private Boolean_Logined;
private String_RemotePath;

private SocketmClientSocket;
private StringmRemoteMessage;
private Int32mBytes;
private Byte[]mBuffer;
private Encoding ASCII;

private StringmReply;
private Int32mRetValue;

///
/// 设置缓冲块的大小
///
private static Int32 BLOCK_SIZE = 512;

public FtpUtil()
{
   _RemotePort   = 21;
   _RemoteAccounts= "Anonymous";
   _RemotePassword= "mack_zhu@hotmail.com";
   _RemotePath   = ".";
   _Logined   = false;

   ASCII    = Encoding.GetEncoding("gb2312");
   mReply    = String.Empty;
   mBuffer    = new Byte;
   mRemoteMessage= String.Empty;
}

///
/// 目前状态是否登录成功了
///
public Boolean Logined
{
   get
   {
    return _Logined;
   }
   set
   {
    _Logined = value;
   }
}

///
/// 路径
///
public String RemotePath
{
   get
   {
    return _RemotePath;
   }
   set
   {
    _RemotePath = value;
   }
}

///
/// 地址
///
public String RemoteHost
{
   get
   {
    return _RemoteHost;
   }
   set
   {
    _RemoteHost = value;
   }
}

///
/// 端口
///
public Int32 RemotePort
{
   get
   {
    return _RemotePort;
   }
   set
   {
    _RemotePort = value;
   }
}

///
/// 帐号
///
public String RemoteAccounts
{
   get
   {
    return _RemoteAccounts;
   }
   set
   {
    _RemoteAccounts = value;
   }
}

///
/// 密码
///
public String RemotePassword
{
   get
   {
    return _RemotePassword;
   }
   set
   {
    _RemotePassword = value;
   }
}

///
/// 登录指定的地址
///
public void Login()
{
   mClientSocket= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   IPEndPoint mEPoint = new IPEndPoint(Dns.Resolve(this.RemoteHost).AddressList, this.RemotePort);
   try
   {
    mClientSocket.Connect(mEPoint);
   }
   catch(Exception)
   {
    throw new IOException("无法联接到指定的IP地址");
   }

   ReadReply();

   if(mRetValue != 220)
   {
    Close();
    throw new IOException(mReply.Substring(4));
   }

   SendCommand("USER "+this.RemoteAccounts);

   if(!(mRetValue == 331 || mRetValue == 230))
   {
    Cleanup();
    throw new IOException(mReply.Substring(4));
   }

   if(mRetValue != 230)
   {
    SendCommand("PASS "+this.RemotePassword);
    if(!(mRetValue == 230 || mRetValue == 202))
    {
   Cleanup();
   throw new IOException(mReply.Substring(4));
    }
   }

   Logined = true;

   Chdir(RemotePath);
}

///
/// 获取目录下的所有文件名
///
/// 文件格式,例如 *.* , *.txt , mack.*
///
public ArrayList GetFileList(string iMask)
{
   if(!Logined)
   {
    Login();
   }

   Socket iSocket = CreateDataSocket();


   SendCommand("NLST " + iMask);

   if(!(mRetValue == 150 || mRetValue == 125))
   {
    throw new IOException(mReply.Substring(4));
   }

   mRemoteMessage = String.Empty;
   

   while(true)
   {
    Int32 iBytes = iSocket.Receive(mBuffer, mBuffer.Length, 0);
    mRemoteMessage += ASCII.GetString(mBuffer, 0, iBytes);

    if(iBytes < mBuffer.Length)
    {
   break;
    }
   }

   Char[] iSeperator = {'\n'};

   ArrayList FileNameList = new ArrayList();

   foreach(String iFileName in mRemoteMessage.Split(iSeperator))
   {
    if(iFileName.Trim() != "")
    {
                  FileNameList.Add(ChangeUTP8(iFileName));
    }
   }

   iSocket.Close();

   ReadReply();

   if(mRetValue != 226)
   {

    throw new IOException(mReply.Substring(4));
   }

   return FileNameList;
}

///
/// 获取服务器端的文件大小
///
///
///
public long GetFileSize(String iFileName)
{

   if(!Logined)
   {
    Login();
   }

   SendCommand("SIZE " + iFileName);

   long iSize=0;

   if(mRetValue == 213)
   {
    iSize = Int64.Parse(mReply.Substring(4));
   }
   else
   {
    throw new IOException(mReply.Substring(4));
   }

   return iSize;
}

///
/// 设置是否需要二进值传输模式
///
///
public void SetBinaryMode(Boolean iMode)
{

   if(iMode)
   {
    SendCommand("TYPE I");
   }
   else
   {
    SendCommand("TYPE A");
   }
   if (mRetValue != 200)
   {
    throw new IOException(mReply.Substring(4));
   }
}

///
/// 下载服务器端的文件
///
/// 服务端的文件名
/// 保存在本地的文件名
public void Download(String iRemoteFileName,String iLocationFileName)
{
   Download(iRemoteFileName,iLocationFileName,false);
}

///
/// 下载服务器端的文件
///
/// 服务端的文件名
/// 保存在本地的文件名
/// 是否需要断点续传
public void Download(String iRemoteFileName,String iLocationFileName,Boolean iResume)
{
   if(!Logined)
   {
    Login();
   }

   SetBinaryMode(true);

   /* Download File RemoteFileName From RemoteHost/RemotePath */

   if (iLocationFileName.Trim() == String.Empty)
   {
    iLocationFileName = iRemoteFileName;
   }

   if(!File.Exists(iLocationFileName))
   {
    Stream iSt = File.Create(iLocationFileName);
    iSt.Close();
   }

   FileStream iOutPut = new FileStream(iLocationFileName,FileMode.Open);
   Socket iSocket = CreateDataSocket();
   long iOffset = 0;

   if(iResume)
   {
    iOffset = iOutPut.Length;

    if(iOffset > 0 )
    {
   SendCommand("REST "+iOffset);
   if(mRetValue != 350)
   {
      //throw new IOException(reply.Substring(4));
      //有些FTP服务器端可能不支持断点续传的功能,从0位置开始传输
      iOffset = 0;
   }
    }

    if(iOffset > 0)
    {
   //如果支持断点续传的就从新设置流的起始值
   long iNPos = iOutPut.Seek(iOffset,SeekOrigin.Begin);
   /*Console.WriteLine("new pos="+npos);*/
    }
   }
   SendCommand("RETR " + iRemoteFileName);
   if(!(mRetValue == 150 || mRetValue == 125))
   {
    throw new IOException(mReply.Substring(4));
   }

   while(true)
   {
    mBytes = iSocket.Receive(mBuffer, mBuffer.Length, 0);
    iOutPut.Write(mBuffer,0,mBytes);

    if(mBytes0 )
   {
    SendCommand("REST " + iOffset);

    if(mRetValue != 350)
    {
   //throw new IOException(reply.Substring(4));
   //有些服务器端是不支持断点续传的

   iOffset = 0;
    }
   }

   SendCommand("STOR "+Path.GetFileName(iFileName));

   if(!(mRetValue == 125 || mRetValue == 150))
   {
    throw new IOException(mReply.Substring(4));
   }

   FileStream iInput = new FileStream(iFileName,FileMode.Open);

   if(iOffset != 0)
   {
    iInput.Seek(iOffset,SeekOrigin.Begin);
   }

   while((mBytes = iInput.Read(mBuffer,0,mBuffer.Length)) > 0)
   {
    iSocket.Send(mBuffer, mBytes, 0);
   }

   iInput.Close();

   if (iSocket.Connected)
   {
    iSocket.Close();
   }

   ReadReply();

   if(!(mRetValue == 226 || mRetValue == 250))
   {
    throw new IOException(mReply.Substring(4));
   }
}

///
/// 删除服务器端的文件名
///
/// 文件名
public void DeleteRemoteFile(String iFileName)
{
   if(!Logined)
   {
    Login();
   }

   SendCommand("DELE "+iFileName);

   if(mRetValue != 250)
   {
    throw new IOException(mReply.Substring(4));
   }
}

///
/// 对服务器端的文件重命名
///
/// 现在的文件名
/// 新的文件名
public void RenameRemoteFile(String iOldFileName,String iNewFileName)
{
   if(!Logined)
   {
    Login();
   }

   SendCommand("RNFR "+iOldFileName);

   if(mRetValue != 350)
   {
    throw new IOException(mReply.Substring(4));
   }

   //提示:FTP服务器端的命令RNTO不会提示你新的文件名是否已重复,它将直接复盖原来那个相同的文件

   SendCommand("RNTO "+iNewFileName);

   if(mRetValue != 250)
   {
    throw new IOException(mReply.Substring(4));
   }
}

///
/// 创建一个服务器端的目录
///
/// 目录名
public void MakeDir(String iDirName)
{
   if(!Logined)
   {
    Login();
   }

   SendCommand("MKD "+iDirName);

   if(mRetValue != 250)
   {
    throw new IOException(mReply.Substring(4));
   }
}

///
/// 移除服务器端的目录
///
/// 目录名
public void RemoveDir(String iDirName)
{
   if(!Logined)
   {
    Login();
   }

   SendCommand("RMD "+iDirName);

   if(mRetValue != 250)
   {
    throw new IOException(mReply.Substring(4));
   }
}


///
/// 创建连接接口
///
///
private Socket CreateDataSocket()
{
   SendCommand("PASV");

   if(mRetValue != 227)
   {
    throw new IOException(mReply.Substring(4));
   }

   Int32 index1= mReply.IndexOf('(');
   Int32 index2= mReply.IndexOf(')');
   String iPData= mReply.Substring(index1+1,index2-index1-1);
   Int32[] iParts= new Int32;
   Int32 iLen   = iPData.Length;
   String iBuf   = String.Empty;
   Int32 iPartCount = 0;

   for (int i = 0; i < iLen && iPartCount
页: [1]
查看完整版本: FTP断点续传的