新建一个工程 FtpClient
添加一个新类 FtpState FTP的状态类
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
class FtpState
{
private ManualResetEvent wait; //等待事件
private FtpWebRequest request; //客户端
private string fileName; //文件名
private Exception operationException = null; //表示在应用程序执行期间发生的错误。
string status; //ftp状态
private string fullLocalPath; //本地路径
public string FullLocalPath
{
get { return fullLocalPath; }
set { fullLocalPath = value; }
}
public FtpState() //构造函数
{
wait = new ManualResetEvent(false);
}
public ManualResetEvent OperationComplete
{
get { return wait; }
}
public FtpWebRequest Request
{
get { return request; }
set { request = value; }
}
public string FileName
{
get { return fileName; }
set { fileName = value; }
}
public Exception OperationException
{
get { return operationException; }
set { operationException = value; }
}
public string StatusDescription
{
get { return status; }
set { status = value; }
}
}
ManualResetEvent:通知一个或多个正在等待的线程已发生事件。
ManualResetEvent(false):用一个指示是否将初始状态设置为终止的布尔值初始化ManualResetEvent类的新实例。如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。
FtpWebRequest : 实现文件传输协议 (FTP) 客户端。
在添加一个类 FTP类 管理FTP的操作的类。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO
class FTP
{
private string strRemoteHost; // FTP服务器IP地址
public string RemoteHost
{
get
{
return strRemoteHost;
}
set
{
strRemoteHost = value;
}
}
private int strRemotePort; // FTP服务器端口
public int RemotePort
{
get
{
return strRemotePort;
}
set
{
strRemotePort = value;
}
}
private string strRemotePath; // 当前服务器目录
public string RemotePath
{
get
{
return strRemotePath;
}
set
{
strRemotePath = value;
}
}
private string strRemoteUser; // 登录用户账号
public string RemoteUser
{
set
{
strRemoteUser = value;
}
}
private string strRemotePass; // 用户登录密码
public string RemotePass
{
set
{
strRemotePass = value;
}
}
private Boolean bConnected; // 是否登录
public bool Connected
{
get
{
return bConnected;
}
}
private string strMsg; // 服务器返回的应答信息(包含应答码)
private string strReply; // 服务器返回的应答信息(包含应答码)
private int iReplyCode; //应答码
private Socket socketControl; //网络通信Socket
private TransferType trType; //传输模式(二进制还是ASCII码)
public enum TransferType //使用枚举自定义类型
{
Binary, ASCII
};
public TransferType GetTransferType() 获取传输模式
{
return trType;
}
private static int BLOCK_SIZE = 512; //设置发送接受的缓存区域
Byte[] buffer = new Byte[BLOCK_SIZE];
Encoding ASCII = Encoding.Default; //获取系统默认ASCII编码方式
public FTP() //缺省构造函数
{
strRemoteHost = "";
strRemotePath = "";
strRemoteUser = "";
strRemotePass = "";
strRemotePort = 21;
bConnected = false;
}
public FTP(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort) //构造函数
{
strRemoteHost = remoteHost;
strRemotePath = remotePath;
strRemoteUser = remoteUser;
strRemotePass = remotePass;
strRemotePort = remotePort;
Connect();//转到 建立连接
}
public FTP(string remoteHost, string remotePath, string remoteUser, string remotePass)
{
strRemoteHost = remoteHost;
strRemotePath = remotePath;
strRemoteUser = remoteUser;
strRemotePass = remotePass;
strRemotePort = 21; //默认端口为21
Connect(); //转到 建立连接
}
public void Connect() //建立连接
{
//创建一个套接字
socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//建立网络连接端口
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRe
motePort);
try
{
socketControl.Connect(ep); //连接远程主机
}
catch (Exception)
{
throw new IOException("Couldn't connect to remote server"); //抛出异常
}
ReadReply(); //转到 获取应答码
if (iReplyCode != 220) //220 对新用户服务准备好
{
DisConnect(); // 转到 退出连接
throw new IOException(strReply.Substring(4));
}
// SendCommand 发送命令
SendCommand("USER " + strRemoteUser); //为用户验证提供用户名
if (!(iReplyCode == 331 || iReplyCode == 230))
//331 用户名正确,需要口令,230用户登录
{
CloseSocketConnect();// 关闭连接,用于登录以前
throw new IOException(strReply.Substring(4));
}
if (iReplyCode != 230)
{
SendCommand("PASS " + strRemotePass); //为用户验证提供密码
if (!(iReplyCode == 230 || iReplyCode == 202)) // 202 命令未实现
{
CloseSocketConnect();//关闭连接,用于登录以前
throw new IOException(strReply.Substring(4));
}
}
bConnected = true;
// 切换到目录
ChDir(strRemotePath);
}
public void DisConnect() //关闭连接
{
if (socketControl != null)
{
SendCommand("QUIT"); // QUIT 退出关闭FTP连接
}
CloseSocketConnect();
}
private void CloseSocketConnect() //关闭连接,用于登录以前
{
if (socketControl != null)
{
socketControl.Close();
socketControl = null;
}
bConnected = false;
}
private void SendCommand(string strCommand) //发送命令
{ //将命令转化为字节型
Byte[] cmdBytes = ASCII.GetBytes((strCommand + "\r\n").ToCharArray());
socketControl.Send(cmdBytes, cmdBytes.Length, 0); //发送命令
ReadReply();
}
private void ReadReply() //获取应答码
{
strMsg = "";
strReply = ReadLine(); // 读取Socket返回的所有字符串
iReplyCode = Int32.Parse(strReply.Substring(0, 3));
}
private string ReadLine() // 读取Socket返回的所有字符串
{
while (true)
{ //接收字节数据,放到缓存中
int iBytes = socketControl.Receive(buffer, buffer.Length, 0);
strMsg += ASCII.GetString(buf
fer, 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;
}
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 string[] Dir(string strMask) //获取文件列表
{
if (!bConnected)// 如果没有连接,则创建连接
{
Connect();
}
//建立进行数据连接的socket
Socket socketData = CreateDataSocket();
//传送命令 nlst 获得目录下的内容
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;
}
private Socket CreateDataSocket()
{
SendCommand("PASV"); //被动模式进行传输
if (iReplyCode != 227) //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));
error parse newif (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("Can't connect to remote server");
}
return s;
}
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 void Delete(string strFileName) //删除文件
{
if (!bConnected)
{
Connect();
}
SendCommand("DELE " + strFileName);
if (iReplyCode != 250)
{
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论