|
原来用WebRequest来传输文件,被人鄙视了。就弄个Socket版的,支持Active,Passive模式。
带事件日志,有时间的人可以拿去做C#版的flashfxp。
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
|
|