Ftp协议Socket实现
原来用WebRequest来传输文件,被人鄙视了。就弄个Socket版的,支持Active,Passive模式。
带事件日志,有时间的人可以拿去做C#版的flashfxp。
public class FtpClient
{
public class FtpLogEventArgs : EventArgs
{
private string mStrLog = string.Empty;
public string Log
{
get
{
return this.mStrLog;
}
}
public FtpLogEventArgs(string strLog)
{
this.mStrLog = strLog;
}
}
public delegate void FtpLogEventHandler(object sender, FtpLogEventArgs e);
public class FtpTranProgressEventArgs : EventArgs
{
private uint mPercent = 0u;
private bool mCancel = false;
public uint Percent
{
get
{
return this.mPercent;
}
}
public bool Cancel
{
get
{
return this.mCancel;
}
set
{
}
}
public FtpTranProgressEventArgs(uint percent)
{
this.mPercent = percent;
this.mCancel = false;
}
}
public delegate void FtpTranProgressEventHandler(object sender, FtpTranProgressEventArgs e);
public enum FtpTransferType
{
Binary,
ASCII
}
public enum FtpMode
{
Active,
Passive
}
public enum FtpSystemType
{
UNIX,
WINDOWS
}
private Socket mSocketConnect = null;
private string mStrServer = string.Empty;
private int mIntPort = ;
private string mStrUser = string.Empty;
private string mStrPassword = string.Empty;
private string mStrPath = string.Empty;
private bool mIsConnected = false;
private FtpMode mMode = FtpMode.Passive;
private FtpSystemType mSystemType = FtpSystemType.UNIX;
private string mStrReply = string.Empty;
private int mIntReplyCode = ;
private static int BLOCK_SIZE = ;
private byte[] mBuffer = new byte[FtpClient.BLOCK_SIZE]; private event FtpLogEventHandler mFtpLogEvent;
public event FtpLogEventHandler FtpLogEvent
{
add
{
FtpLogEventHandler handlerTemp;
FtpLogEventHandler fieldsChanged = this.mFtpLogEvent;
do
{
handlerTemp = fieldsChanged;
FtpLogEventHandler handlerRes = (FtpLogEventHandler)Delegate.Combine(handlerTemp, value);
fieldsChanged = Interlocked.CompareExchange<FtpLogEventHandler>(ref this.mFtpLogEvent, handlerRes, handlerTemp);
}
while (fieldsChanged != handlerTemp);
} remove
{
FtpLogEventHandler handlerTemp;
FtpLogEventHandler fieldsChanged = this.mFtpLogEvent;
do
{
handlerTemp = fieldsChanged;
FtpLogEventHandler handlerRes = (FtpLogEventHandler)Delegate.Remove(handlerTemp, value);
fieldsChanged = Interlocked.CompareExchange<FtpLogEventHandler>(ref this.mFtpLogEvent, handlerRes, handlerTemp);
}
while (fieldsChanged != handlerTemp);
}
} private event FtpTranProgressEventHandler mFtpTranProgressEvent;
public event FtpTranProgressEventHandler FtpTranProgressEvent
{
add
{
FtpTranProgressEventHandler handlerTemp;
FtpTranProgressEventHandler fieldsChanged = this.mFtpTranProgressEvent;
do
{
handlerTemp = fieldsChanged;
FtpTranProgressEventHandler handlerRes = (FtpTranProgressEventHandler)Delegate.Combine(handlerTemp, value);
fieldsChanged = Interlocked.CompareExchange<FtpTranProgressEventHandler>(ref this.mFtpTranProgressEvent, handlerRes, handlerTemp);
}
while (fieldsChanged != handlerTemp);
}
remove
{
FtpTranProgressEventHandler handlerTemp;
FtpTranProgressEventHandler fieldsChanged = this.mFtpTranProgressEvent;
do
{
handlerTemp = fieldsChanged;
FtpTranProgressEventHandler handlerRes = (FtpTranProgressEventHandler)Delegate.Remove(handlerTemp, value);
fieldsChanged = Interlocked.CompareExchange<FtpTranProgressEventHandler>(ref this.mFtpTranProgressEvent, handlerRes, handlerTemp);
}
while (fieldsChanged != handlerTemp);
}
}
public bool Connected
{
get
{
return this.mIsConnected;
}
}
public FtpTransferType TransferType
{
set
{
if (value == FtpTransferType.Binary)
{
this.SendCommand("TYPE I");
}
else
{
this.SendCommand("TYPE A");
}
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
}
public FtpMode Mode
{
get
{
return this.mMode;
}
set
{
this.mMode = value;
}
}
public FtpSystemType SystemType
{
get
{
return this.mSystemType;
}
set
{
this.mSystemType = value;
}
}
protected virtual void OnFtpLogEvent(FtpLogEventArgs e)
{
if (this.mFtpLogEvent != null)
{
this.mFtpLogEvent(this, e);
}
}
protected virtual void OnFtpTranProgressEvent(FtpTranProgressEventArgs e)
{
if (this.mFtpTranProgressEvent != null)
{
this.mFtpTranProgressEvent(this, e);
}
}
public FtpClient(string server, string path, string user, string password, int port, FtpClient.FtpMode mode)
{
this.mStrServer = server;
this.mStrPath = path;
this.mStrUser = user;
this.mStrPassword = password;
this.mIntPort = port;
this.mMode = mode;
}
public void Connect()
{
this.mSocketConnect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPHostEntry ipHost = Dns.GetHostEntry(this.mStrServer);
IPEndPoint iPEndPoint = new IPEndPoint(ipHost.AddressList[], this.mIntPort);
try
{
this.mSocketConnect.Connect(iPEndPoint);
}
catch (Exception)
{
throw new IOException("Couldn't connect to remote server");
}
this.ReadReply();
if (this.mIntReplyCode != )
{
this.DisConnect();
throw new IOException(this.mStrReply.Substring());
}
this.SendCommand("USER " + this.mStrUser);
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
this.CloseSocketConnect();
throw new IOException(this.mStrReply.Substring());
}
if (this.mIntReplyCode == )
{
this.SendCommand("PASS " + this.mStrPassword);
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
this.CloseSocketConnect();
throw new IOException(this.mStrReply.Substring());
}
}
this.SendCommand("SYST");
if (this.mIntReplyCode != )
{
this.CloseSocketConnect();
throw new IOException(this.mStrReply.Substring());
} if (this.mStrReply[].ToString() == "W" || this.mStrReply[].ToString() == "w")
{
this.mSystemType = FtpClient.FtpSystemType.WINDOWS;
}
this.mIsConnected = true;
this.ChDir(this.mStrPath);
}
public void DisConnect()
{
this.CloseSocketConnect();
}
public void ChDir(string strDirName)
{
if (strDirName.Equals(""))
{
return;
}
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("CWD " + strDirName);
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
this.mStrPath = strDirName;
}
public void Reset(long size)
{
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("REST " + size.ToString());
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
public string[] Dir(string strMark)
{
if (!this.mIsConnected)
{
this.Connect();
}
char[] array = new char[]
{
'\n'
};
string text;
string[] result;
if (this.mMode == FtpClient.FtpMode.Active)
{
TcpListener tcpListener = null;
this.CreateDataListener(ref tcpListener);
this.TransferType = FtpClient.FtpTransferType.ASCII;
this.SendCommand("LIST");
Socket socket = tcpListener.AcceptSocket();
text = "";
int num;
do
{
num = socket.Receive(this.mBuffer, this.mBuffer.Length, );
text += Encoding.Default.GetString(this.mBuffer, , num);
}
while (num >= this.mBuffer.Length);
result = text.Split(array);
socket.Close();
tcpListener.Stop();
return result;
}
Socket socket2 = this.CreateDataSocket();
this.SendCommand("LIST");
if (this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
text = "";
int num2;
do
{
num2 = socket2.Receive(this.mBuffer, this.mBuffer.Length, );
text += Encoding.Default.GetString(this.mBuffer, , num2);
}
while (num2 >= this.mBuffer.Length);
result = text.Split(array);
socket2.Close();
if (this.mIntReplyCode != )
{
this.ReadReply();
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
return result;
}
public void UploadFile(string strFile)
{
if (!this.mIsConnected)
{
this.Connect();
}
if (this.mMode == FtpClient.FtpMode.Active)
{
TcpListener tcpListener = null;
this.CreateDataListener(ref tcpListener);
this.TransferType = FtpClient.FtpTransferType.Binary;
this.SendCommand("STOR " + Path.GetFileName(strFile));
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
Socket socket = tcpListener.AcceptSocket();
FileStream fileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long length = fileStream.Length;
long num = 0L;
int num2;
while ((num2 = fileStream.Read(this.mBuffer, , this.mBuffer.Length)) > )
{
num += (long)num2;
uint percent = (uint)(num * 100L / length);
FtpClient.FtpTranProgressEventArgs e = new FtpClient.FtpTranProgressEventArgs(percent);
this.OnFtpTranProgressEvent(e);
socket.Send(this.mBuffer, num2, );
}
fileStream.Close();
if (socket.Connected)
{
socket.Close();
}
tcpListener.Stop();
return;
}
else
{
Socket socket2 = this.CreateDataSocket();
this.SendCommand("STOR " + Path.GetFileName(strFile));
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
FileStream fileStream2 = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long length = fileStream2.Length;
long num = 0L;
int num2;
while ((num2 = fileStream2.Read(this.mBuffer, , this.mBuffer.Length)) > )
{
num += (long)num2;
uint percent = (uint)(num * 100L / length);
FtpClient.FtpTranProgressEventArgs e2 = new FtpClient.FtpTranProgressEventArgs(percent);
this.OnFtpTranProgressEvent(e2);
socket2.Send(this.mBuffer, num2, );
}
fileStream2.Close();
if (socket2.Connected)
{
socket2.Close();
}
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
this.ReadReply();
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
return;
}
}
public void DownloadFile(string strRemoteFileName, string strLocalFolder, string strLocalFileName)
{
if (!this.mIsConnected)
{
this.Connect();
}
if (this.mMode == FtpClient.FtpMode.Active)
{
TcpListener tcpListener = null;
this.CreateDataListener(ref tcpListener);
string extension = Path.GetExtension(strRemoteFileName);
if (extension != ".txt" && extension != ".TXT")
{
this.TransferType = FtpClient.FtpTransferType.Binary;
}
if (strLocalFileName == "")
{
strLocalFileName = strRemoteFileName;
}
FileStream fileStream = new FileStream(strLocalFolder + "\\" + strLocalFileName, FileMode.Create);
this.SendCommand("RETR " + strRemoteFileName);
if (this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != )
{
fileStream.Close();
throw new IOException(this.mStrReply.Substring());
}
Socket socket = tcpListener.AcceptSocket();
while (true)
{
int num = socket.Receive(this.mBuffer, this.mBuffer.Length, );
if (num <= )
{
break;
}
fileStream.Write(this.mBuffer, , num);
}
fileStream.Close();
if (socket.Connected)
{
socket.Close();
}
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
this.ReadReply();
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
tcpListener.Stop();
return;
}
else
{
string extension2 = Path.GetExtension(strRemoteFileName);
if (extension2 != ".txt" && extension2 != ".TXT")
{
this.TransferType = FtpClient.FtpTransferType.Binary;
}
if (strLocalFileName == "")
{
strLocalFileName = strRemoteFileName;
}
FileStream fileStream2 = new FileStream(strLocalFolder + "\\" + strLocalFileName, FileMode.Create);
Socket socket2 = this.CreateDataSocket();
this.SendCommand("RETR " + strRemoteFileName);
if (this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != && this.mIntReplyCode != )
{
fileStream2.Close();
throw new IOException(this.mStrReply.Substring());
}
while (true)
{
int num2 = socket2.Receive(this.mBuffer, this.mBuffer.Length, );
if (num2 <= )
{
break;
}
fileStream2.Write(this.mBuffer, , num2);
}
fileStream2.Close();
if (socket2.Connected)
{
socket2.Close();
}
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
this.ReadReply();
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
return;
}
} public void CreateDir(string strDirName)
{
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("MKD " + strDirName);
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
} public void DeleteDir(string strDirName)
{
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("RMD " + strDirName);
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
} public void DeleteFile(string strFile)
{
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("DELE " + strFile);
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
private long GetFileSize(string strFileName)
{
if (!this.mIsConnected)
{
this.Connect();
}
this.SendCommand("SIZE " + Path.GetFileName(strFileName));
if (this.mIntReplyCode == || this.mIntReplyCode == )
{
return long.Parse(this.mStrReply.Substring());
}
throw new IOException(this.mStrReply.Substring());
}
private string ReadLine()
{
string text = string.Empty;
Thread.Sleep();
int num;
do
{
text = "";
num = this.mSocketConnect.Receive(this.mBuffer, this.mBuffer.Length, );
text += Encoding.Default.GetString(this.mBuffer, , num);
FtpLogEventArgs e = new FtpLogEventArgs("应答: " + text);
this.OnFtpLogEvent(e);
}
while (num >= this.mBuffer.Length);
char[] array = new char[]
{
'\n'
};
string[] array2 = text.Split(array);
if (text.Length > )
{
text = array2[array2.Length - ];
}
else
{
text = array2[];
}
if (!text.Substring(, ).Equals(" "))
{
return this.ReadLine();
}
return text;
}
private void ReadReply()
{
this.mStrReply = this.ReadLine();
this.mIntReplyCode = int.Parse(this.mStrReply.Substring(, ));
}
private void SendCommand(string strCommand)
{
FtpLogEventArgs e = new FtpLogEventArgs("命令: " + strCommand);
this.OnFtpLogEvent(e);
byte[] bytes = Encoding.Default.GetBytes((strCommand + "\r\n").ToCharArray());
this.mSocketConnect.Send(bytes, bytes.Length, );
this.ReadReply();
}
private void CloseSocketConnect()
{
if (this.mSocketConnect != null)
{
this.mSocketConnect.Close();
this.mSocketConnect = null;
}
this.mIsConnected = false;
}
private Socket CreateDataSocket()
{
Socket result;
try
{
this.SendCommand("PASV");
if (this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
int num = this.mStrReply.IndexOf('(');
int num2 = this.mStrReply.IndexOf(')');
string text = this.mStrReply.Substring(num + , num2 - num - );
string[] array = new string[];
array = text.Split(new char[]
{
','
});
if (array.Length != )
{
throw new IOException("Malformed PASV strReply: " + this.mStrReply);
}
string text2 = string.Concat(new string[]
{
array[],
".",
array[],
".",
array[],
".",
array[]
});
try
{
num = int.Parse(array[]);
num2 = int.Parse(array[]);
}
catch
{
throw new IOException("Malformed PASV strReply: " + this.mStrReply);
}
int num3 = (num << ) + num2;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(text2), num3);
try
{
socket.Connect(iPEndPoint);
}
catch (Exception)
{
throw new IOException("Can't connect to remote server");
}
result = socket;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return result;
}
private void CreateDataListener(ref TcpListener listener)
{
string hostName = Dns.GetHostName();
IPAddress iPAddress = Dns.GetHostEntry(hostName).AddressList[];
listener = new TcpListener(iPAddress, );
listener.Start();
IPEndPoint iPEndPoint = (IPEndPoint)listener.LocalEndpoint;
int num = iPEndPoint.Port >> ;
int num2 = iPEndPoint.Port & ;
this.SendCommand(string.Concat(new string[]
{
"PORT ",
iPEndPoint.Address.ToString().Replace(".", ","),
",",
num.ToString(),
",",
num2.ToString()
}));
if (this.mIntReplyCode != && this.mIntReplyCode != )
{
throw new IOException(this.mStrReply.Substring());
}
}
}
简单使用
FtpClient ftpClient = new FtpClient(ip, "/", user, pass, , FtpClient.FtpMode.Passive);
ftpClient.FtpTranProgressEvent += (s, e) =>
{
progress.Value = (int)e.Percent;
Application.DoEvents();
}; try
{
ftpClient.Connect();
}
catch (Exception ex)
{
ftpClient = null;
return;
} if (ftpClient.Connected)
{
ftpClient.CreateDir(root);
ftpClient.ChDir(root); try
{
ftpClient.UploadFile(@"D:\shin_angyo_onshi\Vol_SP\001.jpg");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
return;
}
}
Ftp协议Socket实现的更多相关文章
- day34 异常处理、断言、socket之ftp协议
Python之路,Day20 = 异常处理.断言.socket之ftp协议 参考博客:http://www.cnblogs.com/metianzing/articles/7148191.html 异 ...
- 理解FTP协议
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/5186117. ...
- python之模块ftplib(FTP协议的客户端)
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块ftplib(FTP协议的客户端) #需求:快速进行ftp上传 ,下载,查询文件 from ...
- FTP协议讲解
FTP 概述 文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用.FTP的目标是提高文件的共享性和可靠高效地传送数据. 在传输文件时,FTP 客户端程序先与服务器建立连接 ...
- 初入网络系列笔记(5)FTP协议
一.借鉴说明,本博文借鉴以下博文 1.锤子,FTP协议,http://www.cnblogs.com/loadrunner/archive/2008/01/09/1032264.html 2.suna ...
- FTP协议
1. FTP协议 什么是FTP呢?FTP 是 TCP/IP 协议组中的协议之一,是英文File Transfer Protocol的缩写. 该协议是Internet文件传送的基础,它由一系列规格说明文 ...
- FTP协议及工作原理
1. FTP协议 什么是FTP呢?FTP 是 TCP/IP 协议组中的协议之一,是英文File Transfer Protocol的缩写. 该协议是Internet文件传送的基础,它由一系列规格说明文 ...
- ftp协议详解
客户端与服务器之间,需要多条连接才能完成应用的协议,属于复杂协议.如FTP,PPTP,H.323和SIP均属于复杂协议. 这里主要介绍ftp协议的工作原理.首先,ftp通信协议有两种工作模式,被动模式 ...
- 深入理解FTP协议
文件传输协议FTP(File Transfer Protocol)是因特网中使用最广泛的文件传输协议.FTP使用交互式的访问,允许客户指定文件的类型和格式(如指明是否使用ASCII码),并允许文件具有 ...
随机推荐
- hyperVisors
容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求 期望继续进军中国市场 就像IBM公司,惠普公司和戴尔公司在中国服务器市场的霸主地位一样,Inspu ...
- mysql启动停止,一台服务器跑 多个mysql数据库
一.以非特权用户运行MySQL服务器在讨论如何启动MySQL服务器之前,让我们考虑一下应该以什么用户身份运行MySQL服务器.服务器可以手动或自动启动.如果你手动启动它, 服务器以你登录Unix(Li ...
- Foundation: Binary Search
/* Binary search. * * Implementation history: * 2013-10-5, Mars Fu, first version. */ /* [Binary Sea ...
- oracle的shutdown命令有几种参数
SHUTDOWN NORMAL:不允许新的连接.等待会话结束.等待事务结束.做一个检查点并关闭数据文件.启动时不需要实例恢复.SHUTDOWN TRANSACTIONAL:不允许新的连接.不等待会话结 ...
- AIX Study之--AIX网卡配置管理(ent0、en0、et0)
AIX Study之--AIX网卡配置管理(ent0.en0.et0) 1.查看AIX系统网卡信息: [root@aix211 /]#lsdev |grep et en0 Available 1L- ...
- [Reduc] React Counter Example
Before you use the React Redux bindings, learn how to create a complete simple application with just ...
- Difference between Tomcat's extraResourcePaths and aliases to access an external directory--转
Question: Simple question: In Tomcat7, what's the difference between using extraResourcePaths and al ...
- 《UNIX网络编程》之点对点通信
思路: 点对点通信,其原理也比较简单,在前面回显服务器的基础上,我们分别在服务端和客户端都使用两个线程,一个线程负责发送数据包,一个线程负责接收数据包. 代码如下: 客户端: /*********** ...
- 在Blade中结合gperftools检查内存泄露
Blade是我们开发的大规模C++项目构建工具. gperftools是google开发的性能工具,由高效内存分配器,CPU性能分析器,堆分析器,堆检查器等工具组成. 和其他构建工具不同,结合gtes ...
- asp.net设置元素css的属性
controls.style.Add("css名称","css值") 添加class规则 control.cssclass="str_cssname& ...