|
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 Socket mClientSocket;
private String mRemoteMessage;
private Int32 mBytes;
private Byte[] mBuffer;
private Encoding ASCII;
private String mReply;
private Int32 mRetValue;
///
/// 设置缓冲块的大小
///
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[BLOCK_SIZE];
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[0], 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(mBytes 0 )
{
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[6];
Int32 iLen = iPData.Length;
String iBuf = String.Empty;
Int32 iPartCount = 0;
for (int i = 0; i < iLen && iPartCount |
|
|