用c#怎么实现上传,浏览,下载各种文件 用c#怎么实现上传,浏览,下载各种文件 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这是我写的一个实现在上传下载的dll,绝对可用!using System;using System.IO;using System.Text;using System.Net;using System.Net.Sockets;namespace FTP{ /// <summary> /// Class1 的摘要说明。 /// </summary> public class FtpClient { #region 内部变量 /// <summary> /// 服务器返回的应答信息(包含应答码) /// </summary> private string Msg; /// <summary> /// 服务器返回的应答信息(包含应答码) /// </summary> private string Reply; /// <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]; #endregion #region 构造函数 /// <summary> /// 缺省构造函数 /// </summary> public FtpClient() { remoteHost = ""; remotePath = ""; remoteUser = ""; remotePass = ""; remotePort = 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 ) { remoteHost = remotehost; remotePath = remotepath; remoteUser = remoteuser; remotePass = remotepass; remotePort = remoteport; Connect(); //建立链接 } #endregion #region 登陆 /// <summary> /// FTP服务器IP地址 /// </summary> private string remoteHost; //FTP服务器IP地址 public string RemoteHost //FTP服务器IP地址 { get { return remoteHost; } set { remoteHost = value; } } /// <summary> /// FTP服务器端口 /// </summary> private int remotePort; public int RemotePort { get { return remotePort; } set { remotePort = value; } } /// <summary> /// FTP服务器端口 /// </summary> private string remotePath; public string RemotePath { get { return remotePath; } set { remotePath = value; } } /// <summary> /// 登录用户账号 /// </summary> private string remoteUser; public string RemoteUser { set { remoteUser = value; } } /// <summary> /// 用户登录密码 /// </summary> private string remotePass; public string RemotePass { set { remotePass = value; } } /// <summary> /// 是否已登录 /// </summary> private bool 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), remotePort); // 链接 try { socketControl.Connect(ep); } catch(Exception) { throw new IOException("不能链接到指定的服务器!"); } // 获取应答码 ReadReply(); if(iReplyCode != 220) { DisConnect(); throw new IOException(Reply.Substring(4)); } // 登陆 SendCommand("USER "+remoteUser); if( !(iReplyCode == 331 || iReplyCode == 230) ) { CloseSocketConnect();//关闭连接 throw new IOException(Reply.Substring(4)); } if( iReplyCode != 230 ) { SendCommand("PASS "+remotePass); if( !(iReplyCode == 230 || iReplyCode == 202) ) { CloseSocketConnect();//关闭连接 throw new IOException(Reply.Substring(4)); } } bConnected = true; // 切换到目录 ChDir(remotePath); } /// <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(Reply.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(Reply.Substring(4)); } //获得结果 Msg = ""; while(true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); Msg += Encoding.ASCII.GetString(buffer, 0, iBytes); if(iBytes < buffer.Length) { break; } } char[] seperator = {'\n'}; string[] strsFileList = Msg.Split(seperator); socketData.Close();//数据socket关闭时也会有返回码 if(iReplyCode != 226) { ReadReply(); if(iReplyCode != 226) { throw new IOException(Reply.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(Reply.Substring(4)); } else { throw new IOException(Reply.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(Reply.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(Reply.Substring(4)); } // 如果新文件名与原有文件重名,将覆盖原有文件 SendCommand("RNTO "+strNewFileName); if(iReplyCode != 250) { throw new IOException(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.Substring(4)); } this.remotePath = strDirName; } #endregion #region 内部函数 /// <summary> /// 将一行应答字符串记录在strReply和strMsg,应答码记录在iReplyCode /// </summary> private void ReadReply() { Msg = ""; Reply = ReadLine(); iReplyCode = Int32.Parse(Reply.Substring(0,3)); } /// <summary> /// 建立进行数据连接的socket /// </summary> /// <returns>数据连接socket</returns> private Socket CreateDataSocket() { SendCommand("PASV"); if(iReplyCode != 227) { throw new IOException(Reply.Substring(4)); } int index1 = Reply.IndexOf('('); int index2 = Reply.IndexOf(')'); string ipData = Reply.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: " + Reply); } if (ch == ',' || i+1 == len) { try { parts[partCount++] = Int32.Parse(buf); buf=""; } catch (Exception) { throw new IOException("Malformed PASV strReply: " + Reply); } } } 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; } /// <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); Msg += Encoding.ASCII.GetString(buffer, 0, iBytes); if(iBytes < buffer.Length) //读取完毕 { break; } } char[] seperator = {'\n'}; string[] mess = Msg.Split(seperator); if(Msg.Length > 2) { Msg = mess[mess.Length-2]; //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,但也会分配为空字符串给后面(也是最后一个)字符串数组, //所以最后一个mess是没用的空字符串.但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格 } else { Msg = mess[0]; } if(!Msg.Substring(3,1).Equals(" ")) //返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串) { return ReadLine(); } return Msg; } /// <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 }} c#如何实现在界面form出来之前,出现一段“加载中...”的图像界面,避免UI假死现象 关于wcf传递自定义对象,急,在线等,解决马上结贴 如何为自定义控件添加值为某个结构的属性? 一个多线程 listview问题 VS2010 什么时候出 bate2 或正式版 很困惑的问题。数组 如何从数据库读取数据放入html控件Text中 ? 如何用C#实现 磁盘管理 中的”更改驱动器名和路径“功能? richtxtbox光标重定位问题 关注.net的未来? 如何主listView显示最后一行?垂直流动条移到最大值? 总结了得到应用程序路径的6种方法,大家不用再费劲找了!
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;namespace FTP
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class FtpClient
{ #region 内部变量
/// <summary>
/// 服务器返回的应答信息(包含应答码)
/// </summary>
private string Msg;
/// <summary>
/// 服务器返回的应答信息(包含应答码)
/// </summary>
private string Reply;
/// <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];
#endregion
#region 构造函数
/// <summary>
/// 缺省构造函数
/// </summary>
public FtpClient()
{
remoteHost = "";
remotePath = "";
remoteUser = "";
remotePass = "";
remotePort = 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 )
{
remoteHost = remotehost;
remotePath = remotepath;
remoteUser = remoteuser;
remotePass = remotepass;
remotePort = remoteport;
Connect(); //建立链接
}
#endregion
#region 登陆
/// <summary>
/// FTP服务器IP地址
/// </summary>
private string remoteHost; //FTP服务器IP地址
public string RemoteHost //FTP服务器IP地址
{
get
{
return remoteHost;
}
set
{
remoteHost = value;
}
} /// <summary>
/// FTP服务器端口
/// </summary>
private int remotePort;
public int RemotePort
{
get
{
return remotePort;
}
set
{
remotePort = value;
}
} /// <summary>
/// FTP服务器端口
/// </summary>
private string remotePath;
public string RemotePath
{
get
{
return remotePath;
}
set
{
remotePath = value;
}
} /// <summary>
/// 登录用户账号
/// </summary>
private string remoteUser;
public string RemoteUser
{
set
{
remoteUser = value;
}
} /// <summary>
/// 用户登录密码
/// </summary>
private string remotePass;
public string RemotePass
{
set
{
remotePass = value;
}
} /// <summary>
/// 是否已登录
/// </summary>
private bool 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), remotePort);
// 链接
try
{
socketControl.Connect(ep);
}
catch(Exception)
{
throw new IOException("不能链接到指定的服务器!");
} // 获取应答码
ReadReply();
if(iReplyCode != 220)
{
DisConnect();
throw new IOException(Reply.Substring(4));
} // 登陆
SendCommand("USER "+remoteUser);
if( !(iReplyCode == 331 || iReplyCode == 230) )
{
CloseSocketConnect();//关闭连接
throw new IOException(Reply.Substring(4));
}
if( iReplyCode != 230 )
{
SendCommand("PASS "+remotePass);
if( !(iReplyCode == 230 || iReplyCode == 202) )
{
CloseSocketConnect();//关闭连接
throw new IOException(Reply.Substring(4));
}
}
bConnected = true; // 切换到目录
ChDir(remotePath);
}
/// <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(Reply.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(Reply.Substring(4));
} //获得结果
Msg = "";
while(true)
{
int iBytes = socketData.Receive(buffer, buffer.Length, 0);
Msg += Encoding.ASCII.GetString(buffer, 0, iBytes);
if(iBytes < buffer.Length)
{
break;
}
}
char[] seperator = {'\n'};
string[] strsFileList = Msg.Split(seperator);
socketData.Close();//数据socket关闭时也会有返回码
if(iReplyCode != 226)
{
ReadReply();
if(iReplyCode != 226)
{
throw new IOException(Reply.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(Reply.Substring(4));
}
else
{
throw new IOException(Reply.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(Reply.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(Reply.Substring(4));
}
// 如果新文件名与原有文件重名,将覆盖原有文件
SendCommand("RNTO "+strNewFileName);
if(iReplyCode != 250)
{
throw new IOException(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.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(Reply.Substring(4));
}
this.remotePath = strDirName;
}
#endregion
#region 内部函数
/// <summary>
/// 将一行应答字符串记录在strReply和strMsg,应答码记录在iReplyCode
/// </summary>
private void ReadReply()
{
Msg = "";
Reply = ReadLine();
iReplyCode = Int32.Parse(Reply.Substring(0,3));
} /// <summary>
/// 建立进行数据连接的socket
/// </summary>
/// <returns>数据连接socket</returns>
private Socket CreateDataSocket()
{
SendCommand("PASV");
if(iReplyCode != 227)
{
throw new IOException(Reply.Substring(4));
}
int index1 = Reply.IndexOf('(');
int index2 = Reply.IndexOf(')');
string ipData =
Reply.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: " + Reply);
}
if (ch == ',' || i+1 == len)
{
try
{
parts[partCount++] = Int32.Parse(buf);
buf="";
}
catch (Exception)
{
throw new IOException("Malformed PASV strReply: " + Reply);
}
}
}
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;
} /// <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);
Msg += Encoding.ASCII.GetString(buffer, 0, iBytes);
if(iBytes < buffer.Length) //读取完毕
{
break;
}
}
char[] seperator = {'\n'};
string[] mess = Msg.Split(seperator);
if(Msg.Length > 2)
{
Msg = mess[mess.Length-2];
//seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串,但也会分配为空字符串给后面(也是最后一个)字符串数组,
//所以最后一个mess是没用的空字符串.但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格
}
else
{
Msg = mess[0];
}
if(!Msg.Substring(3,1).Equals(" ")) //返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
{
return ReadLine();
}
return Msg;
} /// <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 }
}