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码),并允许文件具有 ...
随机推荐
- Android Studio SDK更新失败解决方法
1.设置host 首先在windows/system32/drivers/etc/hosts中设置hosts,需要管理员权限.对hosts进行编辑: sudo vim hosts #Google主页 ...
- 可伸缩性/可扩展性(Scalable/scalability)
原文地址:http://www.jdon.com/scalable.html 可伸缩性(可扩展性)是一种对软件系统计算处理能力的设计指标,高可伸缩性代表一种弹性,在系统扩展成长过程中,软件能够保证旺盛 ...
- 黑马程序员_<<properties,打印流,合并流,分割流>>
--------------------ASP.Net+Android+IOS开发..Net培训.期待与您交流! -------------------- 1. Properties 1.概述 Pro ...
- codeforces MemSQL start[c]up Round 2 - online version B 最长公共子系列
题目链接: http://codeforces.com/contest/335/problem/B 分析: 第一眼看上去串的长度为5*10^4, 冒似只能用O(n)的算法可解. 而这样的算法从来没见 ...
- spring3.1的BeanFactory与Quartz1.8整合
spring的applicationContext.xml配置文件: 加入 <bean id="myJob" class="org.springframework. ...
- Retina 屏移动设备 1px解决方案
做移动端H5页面开发时都会遇到这样的问题,用 CSS 定义 1px 的实线边框,在 window.devicePixelRatio=2 的屏幕上会显示成 2px,在 window.devicePix ...
- ssh端口映射,本地转发
应用场景: # HOSTA<-X->HOSTB 表示A,B两机器相互不可以访问, HOSTA<-->HOSTB 表示A,B两机器可以相互访问# 1.localhost< ...
- AssertValid函数学习
转自http://tsitao.blog.163.com/blog/static/29795822006914105840496/ VC的调试中,AssertValid和Dump函数的应用 CObje ...
- Windows 驱动开发 - 5
上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...
- asp.net总结(一)
前言 asp.net的视频不是很多,但是中间由于毕业论文等一些事情.花的时间比较长,知识所以整体上学习的也不是很连贯 打算在总结的时候来复习一下这些知识.只能是大概的来了解asp.net到底有哪些东西 ...