设为首页 收藏本站
查看: 962|回复: 0

Ftp协议Socket实现

[复制链接]

尚未签到

发表于 2015-5-26 09:50:24 | 显示全部楼层 |阅读模式
  原来用WebRequest来传输文件,被人鄙视了。就弄个Socket版的,支持Active,Passive模式。
  带事件日志,有时间的人可以拿去做C#版的flashfxp。


DSC0000.gif DSC0001.gif


  1 public class FtpClient
  2     {
  3         public class FtpLogEventArgs : EventArgs
  4         {
  5             private string mStrLog = string.Empty;
  6             public string Log
  7             {
  8                 get
  9                 {
10                     return this.mStrLog;
11                 }
12             }
13             public FtpLogEventArgs(string strLog)
14             {
15                 this.mStrLog = strLog;
16             }
17         }
18         public delegate void FtpLogEventHandler(object sender, FtpLogEventArgs e);
19         public class FtpTranProgressEventArgs : EventArgs
20         {
21             private uint mPercent = 0u;
22             private bool mCancel = false;
23             public uint Percent
24             {
25                 get
26                 {
27                     return this.mPercent;
28                 }
29             }
30             public bool Cancel
31             {
32                 get
33                 {
34                     return this.mCancel;
35                 }
36                 set
37                 {
38                 }
39             }
40             public FtpTranProgressEventArgs(uint percent)
41             {
42                 this.mPercent = percent;
43                 this.mCancel = false;
44             }
45         }
46         public delegate void FtpTranProgressEventHandler(object sender, FtpTranProgressEventArgs e);
47         public enum FtpTransferType
48         {
49             Binary,
50             ASCII
51         }
52         public enum FtpMode
53         {
54             Active,
55             Passive
56         }
57         public enum FtpSystemType
58         {
59             UNIX,
60             WINDOWS
61         }
62         private Socket mSocketConnect = null;
63         private string mStrServer = string.Empty;
64         private int mIntPort = 21;
65         private string mStrUser = string.Empty;
66         private string mStrPassword = string.Empty;
67         private string mStrPath = string.Empty;
68         private bool mIsConnected = false;
69         private FtpMode mMode = FtpMode.Passive;
70         private FtpSystemType mSystemType = FtpSystemType.UNIX;
71         private string mStrReply = string.Empty;
72         private int mIntReplyCode = 0;
73         private static int BLOCK_SIZE = 2048;
74         private byte[] mBuffer = new byte[FtpClient.BLOCK_SIZE];
75
76         private event FtpLogEventHandler mFtpLogEvent;
77         public event FtpLogEventHandler FtpLogEvent
78         {
79             add
80             {
81                 FtpLogEventHandler handlerTemp;
82                 FtpLogEventHandler fieldsChanged = this.mFtpLogEvent;
83                 do
84                 {
85                     handlerTemp = fieldsChanged;
86                     FtpLogEventHandler handlerRes = (FtpLogEventHandler)Delegate.Combine(handlerTemp, value);
87                     fieldsChanged = Interlocked.CompareExchange(ref this.mFtpLogEvent, handlerRes, handlerTemp);
88                 }
89                 while (fieldsChanged != handlerTemp);
90             }
91
92             remove
93             {
94                 FtpLogEventHandler handlerTemp;
95                 FtpLogEventHandler fieldsChanged = this.mFtpLogEvent;
96                 do
97                 {
98                     handlerTemp = fieldsChanged;
99                     FtpLogEventHandler handlerRes = (FtpLogEventHandler)Delegate.Remove(handlerTemp, value);
100                     fieldsChanged = Interlocked.CompareExchange(ref this.mFtpLogEvent, handlerRes, handlerTemp);
101                 }
102                 while (fieldsChanged != handlerTemp);
103             }
104         }
105
106         private event FtpTranProgressEventHandler mFtpTranProgressEvent;
107         public event FtpTranProgressEventHandler FtpTranProgressEvent
108         {
109             add
110             {
111                 FtpTranProgressEventHandler handlerTemp;
112                 FtpTranProgressEventHandler fieldsChanged = this.mFtpTranProgressEvent;
113                 do
114                 {
115                     handlerTemp = fieldsChanged;
116                     FtpTranProgressEventHandler handlerRes = (FtpTranProgressEventHandler)Delegate.Combine(handlerTemp, value);
117                     fieldsChanged = Interlocked.CompareExchange(ref this.mFtpTranProgressEvent, handlerRes, handlerTemp);
118                 }
119                 while (fieldsChanged != handlerTemp);
120             }
121             remove
122             {
123                 FtpTranProgressEventHandler handlerTemp;
124                 FtpTranProgressEventHandler fieldsChanged = this.mFtpTranProgressEvent;
125                 do
126                 {
127                     handlerTemp = fieldsChanged;
128                     FtpTranProgressEventHandler handlerRes = (FtpTranProgressEventHandler)Delegate.Remove(handlerTemp, value);
129                     fieldsChanged = Interlocked.CompareExchange(ref this.mFtpTranProgressEvent, handlerRes, handlerTemp);
130                 }
131                 while (fieldsChanged != handlerTemp);
132             }
133         }
134         public bool Connected
135         {
136             get
137             {
138                 return this.mIsConnected;
139             }
140         }
141         public FtpTransferType TransferType
142         {
143             set
144             {
145                 if (value == FtpTransferType.Binary)
146                 {
147                     this.SendCommand("TYPE I");
148                 }
149                 else
150                 {
151                     this.SendCommand("TYPE A");
152                 }
153                 if (this.mIntReplyCode != 200)
154                 {
155                     throw new IOException(this.mStrReply.Substring(4));
156                 }
157             }
158         }
159         public FtpMode Mode
160         {
161             get
162             {
163                 return this.mMode;
164             }
165             set
166             {
167                 this.mMode = value;
168             }
169         }
170         public FtpSystemType SystemType
171         {
172             get
173             {
174                 return this.mSystemType;
175             }
176             set
177             {
178                 this.mSystemType = value;
179             }
180         }
181         protected virtual void OnFtpLogEvent(FtpLogEventArgs e)
182         {
183             if (this.mFtpLogEvent != null)
184             {
185                 this.mFtpLogEvent(this, e);
186             }
187         }
188         protected virtual void OnFtpTranProgressEvent(FtpTranProgressEventArgs e)
189         {
190             if (this.mFtpTranProgressEvent != null)
191             {
192                 this.mFtpTranProgressEvent(this, e);
193             }
194         }
195         public FtpClient(string server, string path, string user, string password, int port, FtpClient.FtpMode mode)
196         {
197             this.mStrServer = server;
198             this.mStrPath = path;
199             this.mStrUser = user;
200             this.mStrPassword = password;
201             this.mIntPort = port;
202             this.mMode = mode;
203         }
204         public void Connect()
205         {
206             this.mSocketConnect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
207             IPHostEntry ipHost = Dns.GetHostEntry(this.mStrServer);
208             IPEndPoint iPEndPoint = new IPEndPoint(ipHost.AddressList[0], this.mIntPort);
209             try
210             {
211                 this.mSocketConnect.Connect(iPEndPoint);
212             }
213             catch (Exception)
214             {
215                 throw new IOException("Couldn't connect to remote server");
216             }
217             this.ReadReply();
218             if (this.mIntReplyCode != 220)
219             {
220                 this.DisConnect();
221                 throw new IOException(this.mStrReply.Substring(4));
222             }
223             this.SendCommand("USER " + this.mStrUser);
224             if (this.mIntReplyCode != 331 && this.mIntReplyCode != 230)
225             {
226                 this.CloseSocketConnect();
227                 throw new IOException(this.mStrReply.Substring(4));
228             }
229             if (this.mIntReplyCode == 331)
230             {
231                 this.SendCommand("PASS " + this.mStrPassword);
232                 if (this.mIntReplyCode != 230 && this.mIntReplyCode != 202)
233                 {
234                     this.CloseSocketConnect();
235                     throw new IOException(this.mStrReply.Substring(4));
236                 }
237             }
238             this.SendCommand("SYST");
239             if (this.mIntReplyCode != 215)
240             {
241                 this.CloseSocketConnect();
242                 throw new IOException(this.mStrReply.Substring(4));
243             }
244
245             if (this.mStrReply[4].ToString() == "W" || this.mStrReply[4].ToString() == "w")
246             {
247                 this.mSystemType = FtpClient.FtpSystemType.WINDOWS;
248             }
249             this.mIsConnected = true;
250             this.ChDir(this.mStrPath);
251         }
252         public void DisConnect()
253         {
254             this.CloseSocketConnect();
255         }
256         public void ChDir(string strDirName)
257         {
258             if (strDirName.Equals(""))
259             {
260                 return;
261             }
262             if (!this.mIsConnected)
263             {
264                 this.Connect();
265             }
266             this.SendCommand("CWD " + strDirName);
267             if (this.mIntReplyCode != 250)
268             {
269                 throw new IOException(this.mStrReply.Substring(4));
270             }
271             this.mStrPath = strDirName;
272         }
273         public void Reset(long size)
274         {
275             if (!this.mIsConnected)
276             {
277                 this.Connect();
278             }
279             this.SendCommand("REST " + size.ToString());
280             if (this.mIntReplyCode != 350)
281             {
282                 throw new IOException(this.mStrReply.Substring(4));
283             }
284         }
285         public string[] Dir(string strMark)
286         {
287             if (!this.mIsConnected)
288             {
289                 this.Connect();
290             }
291             char[] array = new char[]
292             {
293                 '\n'
294             };
295             string text;
296             string[] result;
297             if (this.mMode == FtpClient.FtpMode.Active)
298             {
299                 TcpListener tcpListener = null;
300                 this.CreateDataListener(ref tcpListener);
301                 this.TransferType = FtpClient.FtpTransferType.ASCII;
302                 this.SendCommand("LIST");
303                 Socket socket = tcpListener.AcceptSocket();
304                 text = "";
305                 int num;
306                 do
307                 {
308                     num = socket.Receive(this.mBuffer, this.mBuffer.Length, 0);
309                     text += Encoding.Default.GetString(this.mBuffer, 0, num);
310                 }
311                 while (num >= this.mBuffer.Length);
312                 result = text.Split(array);
313                 socket.Close();
314                 tcpListener.Stop();
315                 return result;
316             }
317             Socket socket2 = this.CreateDataSocket();
318             this.SendCommand("LIST");
319             if (this.mIntReplyCode != 150 && this.mIntReplyCode != 125 && this.mIntReplyCode != 226)
320             {
321                 throw new IOException(this.mStrReply.Substring(4));
322             }
323             text = "";
324             int num2;
325             do
326             {
327                 num2 = socket2.Receive(this.mBuffer, this.mBuffer.Length, 0);
328                 text += Encoding.Default.GetString(this.mBuffer, 0, num2);
329             }
330             while (num2 >= this.mBuffer.Length);
331             result = text.Split(array);
332             socket2.Close();
333             if (this.mIntReplyCode != 226)
334             {
335                 this.ReadReply();
336                 if (this.mIntReplyCode != 226)
337                 {
338                     throw new IOException(this.mStrReply.Substring(4));
339                 }
340             }
341             return result;
342         }
343         public void UploadFile(string strFile)
344         {
345             if (!this.mIsConnected)
346             {
347                 this.Connect();
348             }
349             if (this.mMode == FtpClient.FtpMode.Active)
350             {
351                 TcpListener tcpListener = null;
352                 this.CreateDataListener(ref tcpListener);
353                 this.TransferType = FtpClient.FtpTransferType.Binary;
354                 this.SendCommand("STOR " + Path.GetFileName(strFile));
355                 if (this.mIntReplyCode != 125 && this.mIntReplyCode != 150)
356                 {
357                     throw new IOException(this.mStrReply.Substring(4));
358                 }
359                 Socket socket = tcpListener.AcceptSocket();
360                 FileStream fileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
361                 long length = fileStream.Length;
362                 long num = 0L;
363                 int num2;
364                 while ((num2 = fileStream.Read(this.mBuffer, 0, this.mBuffer.Length)) > 0)
365                 {
366                     num += (long)num2;
367                     uint percent = (uint)(num * 100L / length);
368                     FtpClient.FtpTranProgressEventArgs e = new FtpClient.FtpTranProgressEventArgs(percent);
369                     this.OnFtpTranProgressEvent(e);
370                     socket.Send(this.mBuffer, num2, 0);
371                 }
372                 fileStream.Close();
373                 if (socket.Connected)
374                 {
375                     socket.Close();
376                 }
377                 tcpListener.Stop();
378                 return;
379             }
380             else
381             {
382                 Socket socket2 = this.CreateDataSocket();
383                 this.SendCommand("STOR " + Path.GetFileName(strFile));
384                 if (this.mIntReplyCode != 125 && this.mIntReplyCode != 150)
385                 {
386                     throw new IOException(this.mStrReply.Substring(4));
387                 }
388                 FileStream fileStream2 = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
389                 long length = fileStream2.Length;
390                 long num = 0L;
391                 int num2;
392                 while ((num2 = fileStream2.Read(this.mBuffer, 0, this.mBuffer.Length)) > 0)
393                 {
394                     num += (long)num2;
395                     uint percent = (uint)(num * 100L / length);
396                     FtpClient.FtpTranProgressEventArgs e2 = new FtpClient.FtpTranProgressEventArgs(percent);
397                     this.OnFtpTranProgressEvent(e2);
398                     socket2.Send(this.mBuffer, num2, 0);
399                 }
400                 fileStream2.Close();
401                 if (socket2.Connected)
402                 {
403                     socket2.Close();
404                 }
405                 if (this.mIntReplyCode != 226 && this.mIntReplyCode != 250)
406                 {
407                     this.ReadReply();
408                     if (this.mIntReplyCode != 226 && this.mIntReplyCode != 250)
409                     {
410                         throw new IOException(this.mStrReply.Substring(4));
411                     }
412                 }
413                 return;
414             }
415         }
416         public void DownloadFile(string strRemoteFileName, string strLocalFolder, string strLocalFileName)
417         {
418             if (!this.mIsConnected)
419             {
420                 this.Connect();
421             }
422             if (this.mMode == FtpClient.FtpMode.Active)
423             {
424                 TcpListener tcpListener = null;
425                 this.CreateDataListener(ref tcpListener);
426                 string extension = Path.GetExtension(strRemoteFileName);
427                 if (extension != ".txt" && extension != ".TXT")
428                 {
429                     this.TransferType = FtpClient.FtpTransferType.Binary;
430                 }
431                 if (strLocalFileName == "")
432                 {
433                     strLocalFileName = strRemoteFileName;
434                 }
435                 FileStream fileStream = new FileStream(strLocalFolder + "\\" + strLocalFileName, FileMode.Create);
436                 this.SendCommand("RETR " + strRemoteFileName);
437                 if (this.mIntReplyCode != 150 && this.mIntReplyCode != 125 && this.mIntReplyCode != 226 && this.mIntReplyCode != 250 && this.mIntReplyCode != 200)
438                 {
439                     fileStream.Close();
440                     throw new IOException(this.mStrReply.Substring(4));
441                 }
442                 Socket socket = tcpListener.AcceptSocket();
443                 while (true)
444                 {
445                     int num = socket.Receive(this.mBuffer, this.mBuffer.Length, 0);
446                     if (num  2)
584             {
585                 text = array2[array2.Length - 2];
586             }
587             else
588             {
589                 text = array2[0];
590             }
591             if (!text.Substring(3, 1).Equals(" "))
592             {
593                 return this.ReadLine();
594             }
595             return text;
596         }
597         private void ReadReply()
598         {
599             this.mStrReply = this.ReadLine();
600             this.mIntReplyCode = int.Parse(this.mStrReply.Substring(0, 3));
601         }
602         private void SendCommand(string strCommand)
603         {
604             FtpLogEventArgs e = new FtpLogEventArgs("命令:  " + strCommand);
605             this.OnFtpLogEvent(e);
606             byte[] bytes = Encoding.Default.GetBytes((strCommand + "\r\n").ToCharArray());
607             this.mSocketConnect.Send(bytes, bytes.Length, 0);
608             this.ReadReply();
609         }
610         private void CloseSocketConnect()
611         {
612             if (this.mSocketConnect != null)
613             {
614                 this.mSocketConnect.Close();
615                 this.mSocketConnect = null;
616             }
617             this.mIsConnected = false;
618         }
619         private Socket CreateDataSocket()
620         {
621             Socket result;
622             try
623             {
624                 this.SendCommand("PASV");
625                 if (this.mIntReplyCode != 227)
626                 {
627                     throw new IOException(this.mStrReply.Substring(4));
628                 }
629                 int num = this.mStrReply.IndexOf('(');
630                 int num2 = this.mStrReply.IndexOf(')');
631                 string text = this.mStrReply.Substring(num + 1, num2 - num - 1);
632                 string[] array = new string[6];
633                 array = text.Split(new char[]
634                 {
635                     ','
636                 });
637                 if (array.Length != 6)
638                 {
639                     throw new IOException("Malformed PASV strReply: " + this.mStrReply);
640                 }
641                 string text2 = string.Concat(new string[]
642                 {
643                     array[0],
644                     ".",
645                     array[1],
646                     ".",
647                     array[2],
648                     ".",
649                     array[3]
650                 });
651                 try
652                 {
653                     num = int.Parse(array[4]);
654                     num2 = int.Parse(array[5]);
655                 }
656                 catch
657                 {
658                     throw new IOException("Malformed PASV strReply: " + this.mStrReply);
659                 }
660                 int num3 = (num > 8;
687             int num2 = iPEndPoint.Port & 255;
688             this.SendCommand(string.Concat(new string[]
689             {
690                 "PORT ",
691                 iPEndPoint.Address.ToString().Replace(".", ","),
692                 ",",
693                 num.ToString(),
694                 ",",
695                 num2.ToString()
696             }));
697             if (this.mIntReplyCode != 200 && this.mIntReplyCode != 226)
698             {
699                 throw new IOException(this.mStrReply.Substring(4));
700             }
701         }
702     }
View Code   简单使用





1 FtpClient ftpClient = new FtpClient(ip, "/", user, pass, 21, FtpClient.FtpMode.Passive);
2 ftpClient.FtpTranProgressEvent += (s, e) =>
3 {
4     progress.Value = (int)e.Percent;
5     Application.DoEvents();
6 };
7
8 try
9 {
10     ftpClient.Connect();
11 }
12 catch (Exception ex)
13 {
14     ftpClient = null;
15     return;
16 }
17
18   if (ftpClient.Connected)
19   {
20       ftpClient.CreateDir(root);
21       ftpClient.ChDir(root);
22
23   try
24   {
25       ftpClient.UploadFile(@"D:\shin_angyo_onshi\Vol_SP\001.jpg");
26   }
27   catch (Exception ex)
28   {
29       MessageBox.Show(ex.Message.ToString());
30       return;
31   }
32 }
View Code   
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-70793-1-1.html 上篇帖子: jquery-Uploadify上传控件和FTP上传下载删除(含断点续传) 下篇帖子: 实现简单的FTP多线程下载和上传
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表