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码),并允许文件具有 ...
随机推荐
- Test execution order
刚开始的时候,JUnit并没有规定测试方法的调用执行顺序.方法通过映射的API返回的顺序进行调用.然 而,使用JVM顺序是不明智的,因为Java平台没有规定任何特定的顺序,事实上JDK7或多或少的返回 ...
- A - ACM Computer Factory - poj 3436(最大流)
题意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生产线才可以继续加工,比如产品A在生产线1号加工后继续前 ...
- Git Push 不用再次输入用户名和密码方法
前言 在大家使用github的过程中,一定会碰到这样一种情况,就是每次要push 和pull时总是要输入github的账号和密码,这样不仅浪费了大量的时间且降低了工作效率.在此背景下,本文在网上找了两 ...
- SpriteKit游戏开发
http://blog.csdn.net/larrysai/article/category/1663301 http://blog.csdn.net/ping_yun_long/article/de ...
- 子查询in和表连接效率
在数据查询时,尽量减少in子查询而使用表连接的方式进行,效率更高.
- Config配置文件读写
config文件读写操作(文字说明附加在程序中) App.config文件 <?xml version="1.0" encoding="utf-8" ?& ...
- nyoj 44
//nyoj 44 //和上面一题一样,求子串和,但是代码非常简洁..... 时间复杂度为n #include <iostream> using namespace std; int ma ...
- 深入理解BFC和Margin Collapse
深入理解BFC和Margin Collapse BFC的理解与应用 首先我们来看看w3c规范对BFC的解释,其实对于这种概念的学习上,我们总是建议首先寻找官方的定义,因为原则上来说官方的才是最权威 ...
- PHP输出中文乱码的问题(转)
用echo输出的中文显示成乱码, 其实应该是各种服务器脚本都会遇到这个问题, 根本还是编码问题, 一般来说出于编码兼容考虑大多的页面都将页面字符集定义为utf-8 <meta http-equi ...
- Win8节省C盘空间攻略
问题分析: 1.系统页面文件(虚拟内存)占用空间 2.自动更新的缓存文件 3.系统保护的备份文件(系统还原用的) 4.休眠文件 5.索引文件 6.桌面文件 解决办法: 1.机器是8G内存,完全不需要虚 ...