先連接FTP服務器,再設置子路經,然後進行文件的上傳下載操作.
1
using System;
2using System.Net;
3using System.IO;
4using System.Text;
5using System.Net.Sockets;
6
7namespace FTP
8
{
9
/**////
10
/// Summary description for FTPClient.
11
///
12 public class FTPClient
13 {
14 构造函?#region 构造函?
15 /**////
16 /// 缺省构造函?
17 ///
18 public FTPClient()
19 {
20 strRemoteHost = "";
21 strRemotePath = "";
22 strRemoteUser = "";
23 strRemotePass = "";
24 strRemotePort = 21;
25 bConnected = false;
26 }
27
28 /**////
29 /// 构造函?
30 ///
31 ///
32 ///
33 ///
34 ///
35 ///
36 public FTPClient( string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort )
37 {
38 strRemoteHost = remoteHost;
39 strRemotePath = remotePath;
40 strRemoteUser = remoteUser;
41 strRemotePass = remotePass;
42 strRemotePort = remotePort;
43 Connect();
44 }
45 #endregion
46
47 登?#region 登?
48 /**////
49 /// FTP服?器IP地址
50 ///
51 private string strRemoteHost;
52 public string RemoteHost
53 {
54 get
55 {
56 return strRemoteHost;
57 }
58 set
59 {
60 strRemoteHost = value;
61 }
62 }
63 /**////
64 /// FTP服?器端口
65 ///
66 private int strRemotePort;
67 public int RemotePort
68 {
69 get
70 {
71 return strRemotePort;
72 }
73 set
74 {
75 strRemotePort = value;
76 }
77 }
78 /**////
79 /// ?前服?器目?
80 ///
81 private string strRemotePath;
82 public string RemotePath
83 {
84 get
85 {
86 return strRemotePath;
87 }
88 set
89 {
90 strRemotePath = value;
91 }
92 }
93 /**////
94 /// 登?用???
95 ///
96 private string strRemoteUser;
97 public string RemoteUser
98 {
99 set
100 {
101 strRemoteUser = value;
102 }
103 }
104 /**////
105 /// 用?登?密?
106 ///
107 private string strRemotePass;
108 public string RemotePass
109 {
110 set
111 {
112 strRemotePass = value;
113 }
114 }
115
116 /**////
117 /// 是否登?
118 ///
119 private Boolean bConnected;
120 public bool Connected
121 {
122 get
123 {
124 return bConnected;
125 }
126 }
127 #endregion
128
129 ?接#region ?接
130 /**////
131 /// 建立?接
132 ///
133 public void Connect()
134 {
135 socketControl = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
136 IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort);
137 // ?接
138 try
139 {
140 socketControl.Connect(ep);
141 }
142 catch(Exception)
143 {
144 throw new IOException("Couldn't connect to remote server");
145 }
146
147 // ?取?答?
148 ReadReply();
149 if(iReplyCode != 220)
150 {
151 DisConnect();
152 throw new IOException(strReply.Substring(4));
153 }
154
155 // 登?
156 SendCommand("USER "+strRemoteUser);
157 if( !(iReplyCode == 331 || iReplyCode == 230) )
158 {
159 CloseSocketConnect();//???接
160 throw new IOException(strReply.Substring(4));
161 }
162 if( iReplyCode != 230 )
163 {
164 SendCommand("PASS "+strRemotePass);
165 if( !(iReplyCode == 230 || iReplyCode == 202) )
166 {
167 CloseSocketConnect();//???接
168 throw new IOException(strReply.Substring(4));
169 }
170 }
171 bConnected = true;
172
173 // 切?到目?
174 ChDir(strRemotePath);
175 }
176
177
178 /**////
179 /// ???接
180 ///
181 public void DisConnect()
182 {
183 if( socketControl != null )
184 {
185 SendCommand("QUIT");
186 }
187 CloseSocketConnect();
188 }
189
190 #endregion
191
192 ??模式#region ??模式
193
194 /**////
195 /// ??模式:二?制?型、ASCII?型
196 ///
197 public enum TransferType {Binary,ASCII};
198
199 /**////
200 /// ?置??模式
201 ///
202 /// ??模式
203 public void SetTransferType(TransferType ttType)
204 {
205 if(ttType == TransferType.Binary)
206 {
207 SendCommand("TYPE I");//binary?型??
208 }
209 else
210 {
211 SendCommand("TYPE A");//ASCII?型??
212 }
213 if (iReplyCode != 200)
214 {
215 throw new IOException(strReply.Substring(4));
216 }
217 else
218 {
219 trType = ttType;
220 }
221 }
222
223
224 /**////
225 /// ?得??模式
226 ///
227 /// ??模式
228 public TransferType GetTransferType()
229 {
230 return trType;
231 }
232
233 #endregion
234
235 文件操作#region 文件操作
236 /**////
237 /// ?得文件列表
238 ///
239 /// 文件名的匹配字符串
240 ///
241 public string[] Dir(string strMask)
242 {
243 // 建立?接
244 if(!bConnected)
245 {
246 Connect();
247 }
248
249 //建立?行?据?接的socket
250 Socket socketData = CreateDataSocket();
251
252 //?送命令
253 SendCommand("NLST " + strMask);
254
255 //分析?答代?
256 if(!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226))
257 {
258 throw new IOException(strReply.Substring(4));
259 }
260
261 //?得?果
262 strMsg = "";
263 while(true)
264 {
265 int iBytes = socketData.Receive(buffer, buffer.Length, 0);
266 strMsg += ASCII.GetString(buffer, 0, iBytes);
267 if(iBytes < buffer.Length)
268 {
269 break;
270 }
271 }
272 char[] seperator = {'\n'};
273 string[] strsFileList = strMsg.Split(seperator);
274 socketData.Close();//?据socket???也?有返回?
275 if(iReplyCode != 226)
276 {
277 ReadReply();
278 if(iReplyCode != 226)
279 {
280 throw new IOException(strReply.Substring(4));
281 }
282 }
283 return strsFileList;
284 }
285
286
287 /**////
288 /// ?取文件大小
289 ///
290 /// 文件名
291 /// 文件大小
292 private long GetFileSize(string strFileName)
293 {
294 if(!bConnected)
295 {
296 Connect();
297 }
298 SendCommand("SIZE " + Path.GetFileName(strFileName));
299 long lSize=0;
300 if(iReplyCode == 213)
301 {
302 lSize = Int64.Parse(strReply.Substring(4));
303 }
304 else
305 {
306 throw new IOException(strReply.Substring(4));
307 }
308 return lSize;
309 }
310
311
312 /**////
313 /// ?除
314 ///
315 /// 待?除文件名
316 public void Delete(string strFileName)
317 {
318 if(!bConnected)
319 {
320 Connect();
321 }
322 SendCommand("DELE "+strFileName);
323 if(iReplyCode != 250)
324 {
325 throw new IOException(strReply.Substring(4));
326 }
327 }
328
329
330 /**////
331 /// 重命名(如果新文件名与已有文件重名,?覆?已有文件)
332 ///
333 /// ?文件名
334 /// 新文件名
335 public void Rename(string strOldFileName,string strNewFileName)
336 {
337 if(!bConnected)
338 {
339 Connect();
340 }
341 SendCommand("RNFR "+strOldFileName);
342 if(iReplyCode != 350)
343 {
344 throw new IOException(strReply.Substring(4));
345 }
346 // 如果新文件名与原有文件重名,?覆?原有文件
347 SendCommand("RNTO "+strNewFileName);
348 if(iReplyCode != 250)
349 {
350 throw new IOException(strReply.Substring(4));
351 }
352 }
353 #endregion
354
355 上?和下?#region 上?和下?
356 /**////
357 /// 下?一批文件
358 ///
359 /// 文件名的匹配字符串
360 /// 本地目?(不得以\?束)
361 public void Get(string strFileNameMask,string strFolder)
362 {
363 if(!bConnected)
364 {
365 Connect();
366 }
367 string[] strFiles = Dir(strFileNameMask);
368 foreach(string strFile in strFiles)
369 {
370 if(!strFile.Equals(""))//一般??strFiles的最后一?元素可能是空字符串
371 {
372 Get(strFile,strFolder,strFile);
373 }
374 }
375 }
376
377
378 /**////
379 /// 下?一?文件
380 ///
381 /// 要下?的文件名
382 /// 本地目?(不得以\?束)
383 /// 保存在本地?的文件名
384 public void Get(string strRemoteFileName,string strFolder,string strLocalFileName)
385 {
386 if(!bConnected)
387 {
388 Connect();
389 }
390 SetTransferType(TransferType.Binary);
391 if (strLocalFileName.Equals(""))
392 {
393 strLocalFileName = strRemoteFileName;
394 }
395 if(!File.Exists(strLocalFileName))
396 {
397 Stream st = File.Create(strLocalFileName);
398 st.Close();
399 }
400 FileStream output = new
401 FileStream(strFolder + "\\" + strLocalFileName,FileMode.Create);
402 Socket socketData = CreateDataSocket();
403 SendCommand("RETR " + strRemoteFileName);
404 if(!(iReplyCode == 150 || iReplyCode == 125
405 || iReplyCode == 226 || iReplyCode == 250))
406 {
407 throw new IOException(strReply.Substring(4));
408 }
409 while(true)
410 {
411 int iBytes = socketData.Receive(buffer, buffer.Length, 0);
412 output.Write(buffer,0,iBytes);
413 if(iBytes 0)
470 {
471 socketData.Send(buffer, iBytes, 0);
472 }
473 input.Close();
474 if (socketData.Connected)
475 {
476 socketData.Close();
477 }
478 if(!(iReplyCode == 226 || iReplyCode == 250))
479 {
480 ReadReply();
481 if(!(iReplyCode == 226 || iReplyCode == 250))
482 {
483 throw new IOException(strReply.Substring(4));
484 }
485 }
486 }
487
488 #endregion
489
490 目?操作#region 目?操作
491 /**////
492 /// ?建目?
493 ///
494 /// 目?名
495 public void MkDir(string strDirName)
496 {
497 if(!bConnected)
498 {
499 Connect();
500 }
501 SendCommand("MKD "+strDirName);
502 if(iReplyCode != 257)
503 {
504 throw new IOException(strReply.Substring(4));
505 }
506 }
507
508
509 /**////
510 /// ?除目?
511 ///
512 /// 目?名
513 public void RmDir(string strDirName)
514 {
515 if(!bConnected)
516 {
517 Connect();
518 }
519 SendCommand("RMD "+strDirName);
520 if(iReplyCode != 250)
521 {
522 throw new IOException(strReply.Substring(4));
523 }
524 }
525
526
527 /**////
528 /// 改?目?
529 ///
530 /// 新的工作目?名
531 public void ChDir(string strDirName)
532 {
533 if(strDirName.Equals(".") || strDirName.Equals(""))
534 {
535 return;
536 }
537 if(!bConnected)
538 {
539 Connect();
540 }
541 SendCommand("CWD "+strDirName);
542 if(iReplyCode != 250)
543 {
544 throw new IOException(strReply.Substring(4));
545 }
546 this.strRemotePath = strDirName;
547 }
548
549 #endregion
550
551 ?部?量#region ?部?量
552 /**////
553 /// 服?器返回的?答信息(包含?答?)
554 ///
555 private string strMsg;
556 /**////
557 /// 服?器返回的?答信息(包含?答?)
558 ///
559 private string strReply;
560 /**////
561 /// 服?器返回的?答?
562 ///
563 private int iReplyCode;
564 /**////
565 /// ?行控制?接的socket
566 ///
567 private Socket socketControl;
568 /**////
569 /// ??模式
570 ///
571 private TransferType trType;
572 /**////
573 /// 接收和?送?据的???
574 ///
575 private static int BLOCK_SIZE = 512;
576 Byte[] buffer = new Byte[BLOCK_SIZE];
577 /**////
578 /// ??方式
579 ///
580 Encoding ASCII = Encoding.ASCII;
581 #endregion
582
583 ?部函?#region ?部函?
584 /**////
585 /// ?一行?答字符串??在strReply和strMsg
586 /// ?答???在iReplyCode
587 ///
588 private void ReadReply()
589 {
590 strMsg = "";
591 strReply = ReadLine();
592 iReplyCode = Int32.Parse(strReply.Substring(0,3));
593 }
594
595 /**////
596 /// 建立?行?据?接的socket
597 ///
598 /// ?据?接socket
599 private Socket CreateDataSocket()
600 {
601 SendCommand("PASV");
602 if(iReplyCode != 227)
603 {
604 throw new IOException(strReply.Substring(4));
605 }
606 int index1 = strReply.IndexOf('(');
607 int index2 = strReply.IndexOf(')');
608 string ipData =
609 strReply.Substring(index1+1,index2-index1-1);
610 int[] parts = new int[6];
611 int len = ipData.Length;
612 int partCount = 0;
613 string buf="";
614 for (int i = 0; i < len && partCount |