阅读目录
- 关于本文档的说明
- 1.基本介绍
- 2.实际项目
- 3.调用代码参考
- 4.FTPClientHelper下载
- 5.FTP常用的命令
回到目录
关于本文档的说明
本文档使用Socket通信方式来实现ftp文件的上传下载等命令的执行
欢迎传播分享,必须保持原作者的信息,但禁止将该文档直接用于商业盈利。
本人自从几年前走上编程之路,一直致力于收集和总结出好用的框架和通用类库,不管是微软自己的还是第三方的只要实际项目中好用且可以解决实际问题那都会收集好,编写好文章和别人一起分享,这样自己学到了,别人也能学到知识,当今社会很需要知识的搬运工。
Email:707055073@qq.com
本文章地址:http://www.cnblogs.com/wohexiaocai/p/5475506.html
回到目录
1.基本介绍
由于最近的项目是客户端的程序,需要将客户端的图片文件【截图】-【打包】-【ftp上传】,现在就差最后一步了,慢慢的把这些小功能实现了,合并到一起就是一个大功能了,所以一个业务需要拆分的很小很小才可以看清楚,这个项目实际需要用到哪些知识点,下面介绍一下ftp上传的命令
ftp命令的参考链接:http://jingyan.baidu.com/article/b2c186c8ee1116c46ef6ffc8.html,这是我参考的百度,不全的地方还请大家留言告诉我一下。
- ftp适合小文件上传
- 对带宽要求要求较高
- 服务器的安全性也要考虑到
- 命令需要熟悉,不然比较难
回到目录
2.实际项目
- 文件上传
- 文件下载
- 删除文件
- 创建文件夹
- 文件夹重命名
- 删除文件夹
- 改变目录
- 获取文件夹中文件列表
- 等等
2.1 图片上传和下载
写了几个方法,一般用的最多的就是Put,具体的可以下载复制源码下来进行实战一下。
2.2 目录创建和删除
这个方法今天刚好用上了,折腾了一会,才搞定的。
回到目录
3.调用代码参考
由于这个帮助类不是静态的,所以需要实例化
string userName = "xxx";
string password = "xxx";
var ftp = new FTPClientHelper("xxx", ".", userName, password, 1021);
下面还是调用常用的方法,就可以了,因为账号、密码、服务器的IP地址都被我用“xxx”代替了,所以大家自己改下,还有ftp默认端口号是:21,如果有变动还是需要自己改下的。
回到目录
4.FTPClientHelper下载
1 //-------------------------------------------------------------------------------------
2 // All Rights Reserved , Copyright (C) 2015 , ZTO , Ltd .
3 //-------------------------------------------------------------------------------------
4
5 using System;
6 using System.IO;
7 using System.Net;
8 using System.Net.Sockets;
9 using System.Text;
10 using System.Threading;
11
12 namespace ZTO.PicTest.Utilities
13 {
14 /// <summary>
15 /// FTP操作帮助类
16 ///
17 /// 修改纪录
18 ///
19 /// 2016-4-4 版本:1.0 YangHengLian 创建主键,注意命名空间的排序,测试非常好。
20 ///
21 /// 版本:1.0
22 ///
23 /// <author>
24 /// <name>YangHengLian</name>
25 /// <date>2016-4-4</date>
26 /// </author>
27 /// </summary>
28 public class FTPClientHelper
29 {
30 public static object Obj = new object();
31
32 #region 构造函数
33 /// <summary>
34 /// 缺省构造函数
35 /// </summary>
36 public FTPClientHelper()
37 {
38 RemoteHost = "";
39 _strRemotePath = "";
40 _strRemoteUser = "";
41 _strRemotePass = "";
42 _strRemotePort = 21;
43 _bConnected = false;
44 }
45
46 /// <summary>
47 /// 构造函数
48 /// </summary>
49 public FTPClientHelper(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort)
50 {
51 // Ip地址
52 RemoteHost = remoteHost;
53 // 这个很重要,表示连接路径,如果是.表示根目录
54 _strRemotePath = remotePath;
55 // 登录账号
56 _strRemoteUser = remoteUser;
57 // 登录密码
58 _strRemotePass = remotePass;
59 // ftp端口号
60 _strRemotePort = remotePort;
61
62 Connect();
63 }
64 #endregion
65
66 #region 字段
67 private int _strRemotePort;
68 private Boolean _bConnected;
69 private string _strRemotePass;
70 private string _strRemoteUser;
71 private string _strRemotePath;
72
73 /// <summary>
74 /// 服务器返回的应答信息(包含应答码)
75 /// </summary>
76 private string _strMsg;
77 /// <summary>
78 /// 服务器返回的应答信息(包含应答码)
79 /// </summary>
80 private string _strReply;
81 /// <summary>
82 /// 服务器返回的应答码
83 /// </summary>
84 private int _iReplyCode;
85 /// <summary>
86 /// 进行控制连接的socket
87 /// </summary>
88 private Socket _socketControl;
89 /// <summary>
90 /// 传输模式
91 /// </summary>
92 private TransferType _trType;
93
94 /// <summary>
95 /// 接收和发送数据的缓冲区
96 /// </summary>
97 private const int BlockSize = 512;
98
99 /// <summary>
100 /// 编码方式
101 /// </summary>
102 readonly Encoding _ascii = Encoding.ASCII;
103 /// <summary>
104 /// 字节数组
105 /// </summary>
106 readonly Byte[] _buffer = new Byte[BlockSize];
107 #endregion
108
109 #region 属性
110
111 /// <summary>
112 /// FTP服务器IP地址
113 /// </summary>
114 public string RemoteHost { get; set; }
115
116 /// <summary>
117 /// FTP服务器端口
118 /// </summary>
119 public int RemotePort
120 {
121 get
122 {
123 return _strRemotePort;
124 }
125 set
126 {
127 _strRemotePort = value;
128 }
129 }
130
131 /// <summary>
132 /// 当前服务器目录
133 /// </summary>
134 public string RemotePath
135 {
136 get
137 {
138 return _strRemotePath;
139 }
140 set
141 {
142 _strRemotePath = value;
143 }
144 }
145
146 /// <summary>
147 /// 登录用户账号
148 /// </summary>
149 public string RemoteUser
150 {
151 set
152 {
153 _strRemoteUser = value;
154 }
155 }
156
157 /// <summary>
158 /// 用户登录密码
159 /// </summary>
160 public string RemotePass
161 {
162 set
163 {
164 _strRemotePass = value;
165 }
166 }
167
168 /// <summary>
169 /// 是否登录
170 /// </summary>
171 public bool Connected
172 {
173 get
174 {
175 return _bConnected;
176 }
177 }
178 #endregion
179
180 #region 链接
181 /// <summary>
182 /// 建立连接
183 /// </summary>
184 public void Connect()
185 {
186 lock (Obj)
187 {
188 _socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
189 var ep = new IPEndPoint(IPAddress.Parse(RemoteHost), _strRemotePort);
190 try
191 {
192 _socketControl.Connect(ep);
193 }
194 catch (Exception)
195 {
196 throw new IOException("不能连接ftp服务器");
197 }
198 }
199 ReadReply();
200 if (_iReplyCode != 220)
201 {
202 DisConnect();
203 throw new IOException(_strReply.Substring(4));
204 }
205 SendCommand("USER " + _strRemoteUser);
206 if (!(_iReplyCode == 331 || _iReplyCode == 230))
207 {
208 CloseSocketConnect();
209 throw new IOException(_strReply.Substring(4));
210 }
211 if (_iReplyCode != 230)
212 {
213 SendCommand("PASS " + _strRemotePass);
214 if (!(_iReplyCode == 230 || _iReplyCode == 202))
215 {
216 CloseSocketConnect();
217 throw new IOException(_strReply.Substring(4));
218 }
219 }
220 _bConnected = true;
221 ChDir(_strRemotePath);
222 }
223
224 /// <summary>
225 /// 关闭连接
226 /// </summary>
227 public void DisConnect()
228 {
229 if (_socketControl != null)
230 {
231 SendCommand("QUIT");
232 }
233 CloseSocketConnect();
234 }
235 #endregion
236
237 #region 传输模式
238 /// <summary>
239 /// 传输模式:二进制类型、ASCII类型
240 /// </summary>
241 public enum TransferType { Binary, ASCII };
242
243 /// <summary>
244 /// 设置传输模式
245 /// </summary>
246 /// <param name="ttType">传输模式</param>
247 public void SetTransferType(TransferType ttType)
248 {
249 SendCommand(ttType == TransferType.Binary ? "TYPE I" : "TYPE A");
250 if (_iReplyCode != 200)
251 {
252 throw new IOException(_strReply.Substring(4));
253 }
254 _trType = ttType;
255 }
256
257 /// <summary>
258 /// 获得传输模式
259 /// </summary>
260 /// <returns>传输模式</returns>
261 public TransferType GetTransferType()
262 {
263 return _trType;
264 }
265 #endregion
266
267 #region 文件操作
268 /// <summary>
269 /// 获得文件列表
270 /// </summary>
271 /// <param name="strMask">文件名的匹配字符串</param>
272 public string[] Dir(string strMask)
273 {
274 if (!_bConnected)
275 {
276 Connect();
277 }
278 Socket socketData = CreateDataSocket();
279 SendCommand("NLST " + strMask);
280 if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226))
281 {
282 throw new IOException(_strReply.Substring(4));
283 }
284 _strMsg = "";
285 Thread.Sleep(2000);
286 while (true)
287 {
288 int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
289 _strMsg += _ascii.GetString(_buffer, 0, iBytes);
290 if (iBytes < _buffer.Length)
291 {
292 break;
293 }
294 }
295 char[] seperator = { '\n' };
296 string[] strsFileList = _strMsg.Split(seperator);
297 socketData.Close(); //数据socket关闭时也会有返回码
298 if (_iReplyCode != 226)
299 {
300 ReadReply();
301 if (_iReplyCode != 226)
302 {
303
304 throw new IOException(_strReply.Substring(4));
305 }
306 }
307 return strsFileList;
308 }
309
310 public void NewPutByGuid(string strFileName, string strGuid)
311 {
312 if (!_bConnected)
313 {
314 Connect();
315 }
316 string str = strFileName.Substring(0, strFileName.LastIndexOf("\\", StringComparison.Ordinal));
317 string strTypeName = strFileName.Substring(strFileName.LastIndexOf(".", StringComparison.Ordinal));
318 strGuid = str + "\\" + strGuid;
319 Socket socketData = CreateDataSocket();
320 SendCommand("STOR " + Path.GetFileName(strGuid));
321 if (!(_iReplyCode == 125 || _iReplyCode == 150))
322 {
323 throw new IOException(_strReply.Substring(4));
324 }
325 var input = new FileStream(strGuid, FileMode.Open);
326 input.Flush();
327 int iBytes;
328 while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
329 {
330 socketData.Send(_buffer, iBytes, 0);
331 }
332 input.Close();
333 if (socketData.Connected)
334 {
335 socketData.Close();
336 }
337 if (!(_iReplyCode == 226 || _iReplyCode == 250))
338 {
339 ReadReply();
340 if (!(_iReplyCode == 226 || _iReplyCode == 250))
341 {
342 throw new IOException(_strReply.Substring(4));
343 }
344 }
345 }
346
347 /// <summary>
348 /// 获取文件大小
349 /// </summary>
350 /// <param name="strFileName">文件名</param>
351 /// <returns>文件大小</returns>
352 public long GetFileSize(string strFileName)
353 {
354 if (!_bConnected)
355 {
356 Connect();
357 }
358 SendCommand("SIZE " + Path.GetFileName(strFileName));
359 long lSize;
360 if (_iReplyCode == 213)
361 {
362 lSize = Int64.Parse(_strReply.Substring(4));
363 }
364 else
365 {
366 throw new IOException(_strReply.Substring(4));
367 }
368 return lSize;
369 }
370
371 /// <summary>
372 /// 获取文件信息
373 /// </summary>
374 /// <param name="strFileName">文件名</param>
375 /// <returns>文件大小</returns>
376 public string GetFileInfo(string strFileName)
377 {
378 if (!_bConnected)
379 {
380 Connect();
381 }
382 Socket socketData = CreateDataSocket();
383 SendCommand("LIST " + strFileName);
384 if (!(_iReplyCode == 150 || _iReplyCode == 125
385 || _iReplyCode == 226 || _iReplyCode == 250))
386 {
387 throw new IOException(_strReply.Substring(4));
388 }
389 byte[] b = new byte[512];
390 MemoryStream ms = new MemoryStream();
391
392 while (true)
393 {
394 int iBytes = socketData.Receive(b, b.Length, 0);
395 ms.Write(b, 0, iBytes);
396 if (iBytes <= 0)
397 {
398
399 break;
400 }
401 }
402 byte[] bt = ms.GetBuffer();
403 string strResult = Encoding.ASCII.GetString(bt);
404 ms.Close();
405 return strResult;
406 }
407
408 /// <summary>
409 /// 删除
410 /// </summary>
411 /// <param name="strFileName">待删除文件名</param>
412 public void Delete(string strFileName)
413 {
414 if (!_bConnected)
415 {
416 Connect();
417 }
418 SendCommand("DELE " + strFileName);
419 if (_iReplyCode != 250)
420 {
421 throw new IOException(_strReply.Substring(4));
422 }
423 }
424
425 /// <summary>
426 /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件)
427 /// </summary>
428 /// <param name="strOldFileName">旧文件名</param>
429 /// <param name="strNewFileName">新文件名</param>
430 public void Rename(string strOldFileName, string strNewFileName)
431 {
432 if (!_bConnected)
433 {
434 Connect();
435 }
436 SendCommand("RNFR " + strOldFileName);
437 if (_iReplyCode != 350)
438 {
439 throw new IOException(_strReply.Substring(4));
440 }
441 // 如果新文件名与原有文件重名,将覆盖原有文件
442 SendCommand("RNTO " + strNewFileName);
443 if (_iReplyCode != 250)
444 {
445 throw new IOException(_strReply.Substring(4));
446 }
447 }
448 #endregion
449
450 #region 上传和下载
451 /// <summary>
452 /// 下载一批文件
453 /// </summary>
454 /// <param name="strFileNameMask">文件名的匹配字符串</param>
455 /// <param name="strFolder">本地目录(不得以\结束)</param>
456 public void Get(string strFileNameMask, string strFolder)
457 {
458 if (!_bConnected)
459 {
460 Connect();
461 }
462 string[] strFiles = Dir(strFileNameMask);
463 foreach (string strFile in strFiles)
464 {
465 if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串
466 {
467 Get(strFile, strFolder, strFile);
468 }
469 }
470 }
471
472 /// <summary>
473 /// 下载一个文件
474 /// </summary>
475 /// <param name="strRemoteFileName">要下载的文件名</param>
476 /// <param name="strFolder">本地目录(不得以\结束)</param>
477 /// <param name="strLocalFileName">保存在本地时的文件名</param>
478 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName)
479 {
480 Socket socketData = CreateDataSocket();
481 try
482 {
483 if (!_bConnected)
484 {
485 Connect();
486 }
487 SetTransferType(TransferType.Binary);
488 if (strLocalFileName.Equals(""))
489 {
490 strLocalFileName = strRemoteFileName;
491 }
492 SendCommand("RETR " + strRemoteFileName);
493 if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250))
494 {
495 throw new IOException(_strReply.Substring(4));
496 }
497 var output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);
498 while (true)
499 {
500 int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
501 output.Write(_buffer, 0, iBytes);
502 if (iBytes <= 0)
503 {
504 break;
505 }
506 }
507 output.Close();
508 if (socketData.Connected)
509 {
510 socketData.Close();
511 }
512 if (!(_iReplyCode == 226 || _iReplyCode == 250))
513 {
514 ReadReply();
515 if (!(_iReplyCode == 226 || _iReplyCode == 250))
516 {
517 throw new IOException(_strReply.Substring(4));
518 }
519 }
520 }
521 catch
522 {
523 socketData.Close();
524 _socketControl.Close();
525 _bConnected = false;
526 _socketControl = null;
527 }
528 }
529
530 /// <summary>
531 /// 下载一个文件
532 /// </summary>
533 /// <param name="strRemoteFileName">要下载的文件名</param>
534 /// <param name="strFolder">本地目录(不得以\结束)</param>
535 /// <param name="strLocalFileName">保存在本地时的文件名</param>
536 public void GetNoBinary(string strRemoteFileName, string strFolder, string strLocalFileName)
537 {
538 if (!_bConnected)
539 {
540 Connect();
541 }
542
543 if (strLocalFileName.Equals(""))
544 {
545 strLocalFileName = strRemoteFileName;
546 }
547 Socket socketData = CreateDataSocket();
548 SendCommand("RETR " + strRemoteFileName);
549 if (!(_iReplyCode == 150 || _iReplyCode == 125 || _iReplyCode == 226 || _iReplyCode == 250))
550 {
551 throw new IOException(_strReply.Substring(4));
552 }
553 var output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create);
554 while (true)
555 {
556 int iBytes = socketData.Receive(_buffer, _buffer.Length, 0);
557 output.Write(_buffer, 0, iBytes);
558 if (iBytes <= 0)
559 {
560 break;
561 }
562 }
563 output.Close();
564 if (socketData.Connected)
565 {
566 socketData.Close();
567 }
568 if (!(_iReplyCode == 226 || _iReplyCode == 250))
569 {
570 ReadReply();
571 if (!(_iReplyCode == 226 || _iReplyCode == 250))
572 {
573 throw new IOException(_strReply.Substring(4));
574 }
575 }
576 }
577
578 /// <summary>
579 /// 上传一批文件
580 /// </summary>
581 /// <param name="strFolder">本地目录(不得以\结束)</param>
582 /// <param name="strFileNameMask">文件名匹配字符(可以包含*和?)</param>
583 public void Put(string strFolder, string strFileNameMask)
584 {
585 string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask);
586 foreach (string strFile in strFiles)
587 {
588 Put(strFile);
589 }
590 }
591
592 /// <summary>
593 /// 上传一个文件
594 /// </summary>
595 /// <param name="strFileName">本地文件名</param>
596 public void Put(string strFileName)
597 {
598 if (!_bConnected)
599 {
600 Connect();
601 }
602 Socket socketData = CreateDataSocket();
603 if (Path.GetExtension(strFileName) == "")
604 SendCommand("STOR " + Path.GetFileNameWithoutExtension(strFileName));
605 else
606 SendCommand("STOR " + Path.GetFileName(strFileName));
607
608 if (!(_iReplyCode == 125 || _iReplyCode == 150))
609 {
610 throw new IOException(_strReply.Substring(4));
611 }
612
613 var input = new FileStream(strFileName, FileMode.Open);
614 int iBytes;
615 while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
616 {
617 socketData.Send(_buffer, iBytes, 0);
618 }
619 input.Close();
620 if (socketData.Connected)
621 {
622 socketData.Close();
623 }
624 if (!(_iReplyCode == 226 || _iReplyCode == 250))
625 {
626 ReadReply();
627 if (!(_iReplyCode == 226 || _iReplyCode == 250))
628 {
629 throw new IOException(_strReply.Substring(4));
630 }
631 }
632 }
633
634 /// <summary>
635 /// 上传一个文件
636 /// </summary>
637 /// <param name="strFileName">本地文件名</param>
638 ///
639 /// <param name="strGuid"> </param>
640 public void PutByGuid(string strFileName, string strGuid)
641 {
642 if (!_bConnected)
643 {
644 Connect();
645 }
646 string str = strFileName.Substring(0, strFileName.LastIndexOf("\\", StringComparison.Ordinal));
647 string strTypeName = strFileName.Substring(strFileName.LastIndexOf(".", System.StringComparison.Ordinal));
648 strGuid = str + "\\" + strGuid;
649 File.Copy(strFileName, strGuid);
650 File.SetAttributes(strGuid, FileAttributes.Normal);
651 Socket socketData = CreateDataSocket();
652 SendCommand("STOR " + Path.GetFileName(strGuid));
653 if (!(_iReplyCode == 125 || _iReplyCode == 150))
654 {
655 throw new IOException(_strReply.Substring(4));
656 }
657 var input = new FileStream(strGuid, FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
658 int iBytes = 0;
659 while ((iBytes = input.Read(_buffer, 0, _buffer.Length)) > 0)
660 {
661 socketData.Send(_buffer, iBytes, 0);
662 }
663 input.Close();
664 File.Delete(strGuid);
665 if (socketData.Connected)
666 {
667 socketData.Close();
668 }
669 if (!(_iReplyCode == 226 || _iReplyCode == 250))
670 {
671 ReadReply();
672 if (!(_iReplyCode == 226 || _iReplyCode == 250))
673 {
674 throw new IOException(_strReply.Substring(4));
675 }
676 }
677 }
678 #endregion
679
680 #region 目录操作
681 /// <summary>
682 /// 创建目录
683 /// </summary>
684 /// <param name="strDirName">目录名</param>
685 public void MkDir(string strDirName)
686 {
687 if (!_bConnected)
688 {
689 Connect();
690 }
691 SendCommand("MKD " + strDirName);
692 if (_iReplyCode != 257)
693 {
694 throw new IOException(_strReply.Substring(4));
695 }
696 }
697
698 /// <summary>
699 /// 删除目录
700 /// </summary>
701 /// <param name="strDirName">目录名</param>
702 public void RmDir(string strDirName)
703 {
704 if (!_bConnected)
705 {
706 Connect();
707 }
708 SendCommand("RMD " + strDirName);
709 if (_iReplyCode != 250)
710 {
711 throw new IOException(_strReply.Substring(4));
712 }
713 }
714
715 /// <summary>
716 /// 改变目录
717 /// </summary>
718 /// <param name="strDirName">新的工作目录名</param>
719 public void ChDir(string strDirName)
720 {
721 if (strDirName.Equals(".") || strDirName.Equals(""))
722 {
723 return;
724 }
725 if (!_bConnected)
726 {
727 Connect();
728 }
729 SendCommand("CWD " + strDirName);
730 if (_iReplyCode != 250)
731 {
732 throw new IOException(_strReply.Substring(4));
733 }
734 this._strRemotePath = strDirName;
735 }
736 #endregion
737
738 #region 内部函数
739 /// <summary>
740 /// 将一行应答字符串记录在strReply和strMsg,应答码记录在iReplyCode
741 /// </summary>
742 private void ReadReply()
743 {
744 _strMsg = "";
745 _strReply = ReadLine();
746 _iReplyCode = Int32.Parse(_strReply.Substring(0, 3));
747 }
748
749 /// <summary>
750 /// 建立进行数据连接的socket
751 /// </summary>
752 /// <returns>数据连接socket</returns>
753 private Socket CreateDataSocket()
754 {
755 SendCommand("PASV");
756 if (_iReplyCode != 227)
757 {
758 throw new IOException(_strReply.Substring(4));
759 }
760 int index1 = _strReply.IndexOf('(');
761 int index2 = _strReply.IndexOf(')');
762 string ipData = _strReply.Substring(index1 + 1, index2 - index1 - 1);
763 int[] parts = new int[6];
764 int len = ipData.Length;
765 int partCount = 0;
766 string buf = "";
767 for (int i = 0; i < len && partCount <= 6; i++)
768 {
769 char ch = Char.Parse(ipData.Substring(i, 1));
770 if (Char.IsDigit(ch))
771 buf += ch;
772 else if (ch != ',')
773 {
774 throw new IOException("Malformed PASV strReply: " + _strReply);
775 }
776 if (ch == ',' || i + 1 == len)
777 {
778 try
779 {
780 parts[partCount++] = Int32.Parse(buf);
781 buf = "";
782 }
783 catch (Exception)
784 {
785 throw new IOException("Malformed PASV strReply: " + _strReply);
786 }
787 }
788 }
789 string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
790 int port = (parts[4] << 8) + parts[5];
791 var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
792 var ep = new IPEndPoint(IPAddress.Parse(ipAddress), port);
793 try
794 {
795 s.Connect(ep);
796 }
797 catch (Exception)
798 {
799 throw new IOException("无法连接ftp服务器");
800 }
801 return s;
802 }
803
804 /// <summary>
805 /// 关闭socket连接(用于登录以前)
806 /// </summary>
807 private void CloseSocketConnect()
808 {
809 lock (Obj)
810 {
811 if (_socketControl != null)
812 {
813 _socketControl.Close();
814 _socketControl = null;
815 }
816 _bConnected = false;
817 }
818 }
819
820 /// <summary>
821 /// 读取Socket返回的所有字符串
822 /// </summary>
823 /// <returns>包含应答码的字符串行</returns>
824 private string ReadLine()
825 {
826 lock (Obj)
827 {
828 while (true)
829 {
830 int iBytes = _socketControl.Receive(_buffer, _buffer.Length, 0);
831 _strMsg += _ascii.GetString(_buffer, 0, iBytes);
832 if (iBytes < _buffer.Length)
833 {
834 break;
835 }
836 }
837 }
838 char[] seperator = { '\n' };
839 string[] mess = _strMsg.Split(seperator);
840 if (_strMsg.Length > 2)
841 {
842 _strMsg = mess[mess.Length - 2];
843 }
844 else
845 {
846 _strMsg = mess[0];
847 }
848 if (!_strMsg.Substring(3, 1).Equals(" ")) //返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串)
849 {
850 return ReadLine();
851 }
852 return _strMsg;
853 }
854
855 /// <summary>
856 /// 发送命令并获取应答码和最后一行应答字符串
857 /// </summary>
858 /// <param name="strCommand">命令</param>
859 public void SendCommand(String strCommand)
860 {
861 lock (Obj)
862 {
863 Byte[] cmdBytes = Encoding.ASCII.GetBytes((strCommand + "\r\n").ToCharArray());
864 _socketControl.Send(cmdBytes, cmdBytes.Length, 0);
865 Thread.Sleep(100);
866 ReadReply();
867 }
868 }
869 #endregion
870 }
871 }
回到目录
5.FTP常用的命令
1 #region 程序集 System.dll, v4.0.0.0
2 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll
3 #endregion
4
5 using System;
6
7 namespace System.Net
8 {
9 // 摘要:
10 // System.Net.WebRequestMethods.Ftp、System.Net.WebRequestMethods.File 和 System.Net.WebRequestMethods.Http
11 // 类的容器类。无法继承此类
12 public static class WebRequestMethods
13 {
14
15 // 摘要:
16 // 表示可用于 FILE 请求的文件协议方法的类型。无法继承此类。
17 public static class File
18 {
19 // 摘要:
20 // 表示用来从指定的位置检索文件的 FILE GET 协议方法。
21 public const string DownloadFile = "GET";
22 //
23 // 摘要:
24 // 表示用来将文件复制到指定位置的 FILE PUT 协议方法。
25 public const string UploadFile = "PUT";
26 }
27
28 // 摘要:
29 // 表示可与 FTP 请求一起使用的 FTP 协议方法的类型。无法继承此类。
30 public static class Ftp
31 {
32 // 摘要:
33 // 表示要用于将文件追加到 FTP 服务器上的现有文件的 FTP APPE 协议方法。
34 public const string AppendFile = "APPE";
35 //
36 // 摘要:
37 // 表示要用于删除 FTP 服务器上的文件的 FTP DELE 协议方法。
38 public const string DeleteFile = "DELE";
39 //
40 // 摘要:
41 // 表示要用于从 FTP 服务器下载文件的 FTP RETR 协议方法。
42 public const string DownloadFile = "RETR";
43 //
44 // 摘要:
45 // 表示要用于从 FTP 服务器上的文件检索日期时间戳的 FTP MDTM 协议方法。
46 public const string GetDateTimestamp = "MDTM";
47 //
48 // 摘要:
49 // 表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。
50 public const string GetFileSize = "SIZE";
51 //
52 // 摘要:
53 // 表示获取 FTP 服务器上的文件的简短列表的 FTP NLIST 协议方法。
54 public const string ListDirectory = "NLST";
55 //
56 // 摘要:
57 // 表示获取 FTP 服务器上的文件的详细列表的 FTP LIST 协议方法。
58 public const string ListDirectoryDetails = "LIST";
59 //
60 // 摘要:
61 // 表示在 FTP 服务器上创建目录的 FTP MKD 协议方法。
62 public const string MakeDirectory = "MKD";
63 //
64 // 摘要:
65 // 表示打印当前工作目录的名称的 FTP PWD 协议方法。
66 public const string PrintWorkingDirectory = "PWD";
67 //
68 // 摘要:
69 // 表示移除目录的 FTP RMD 协议方法。
70 public const string RemoveDirectory = "RMD";
71 //
72 // 摘要:
73 // 表示重命名目录的 FTP RENAME 协议方法。
74 public const string Rename = "RENAME";
75 //
76 // 摘要:
77 // 表示将文件上载到 FTP 服务器的 FTP STOR 协议方法。
78 public const string UploadFile = "STOR";
79 //
80 // 摘要:
81 // 表示将具有唯一名称的文件上载到 FTP 服务器的 FTP STOU 协议方法。
82 public const string UploadFileWithUniqueName = "STOU";
83 }
84
85 // 摘要:
86 // 表示可与 HTTP 请求一起使用的 HTTP 协议方法的类型。
87 public static class Http
88 {
89 // 摘要:
90 // 表示与代理一起使用的 HTTP CONNECT 协议方法,该代理可以动态切换到隧道,如 SSL 隧道的情况。
91 public const string Connect = "CONNECT";
92 //
93 // 摘要:
94 // 表示一个 HTTP GET 协议方法。
95 public const string Get = "GET";
96 //
97 // 摘要:
98 // 表示一个 HTTP HEAD 协议方法。除了服务器在响应中只返回消息头不返回消息体以外,HEAD 方法和 GET 是一样的。
99 public const string Head = "HEAD";
100 //
101 // 摘要:
102 // 表示一个 HTTP MKCOL 请求,该请求在请求 URI(统一资源标识符)指定的位置新建集合,如页的集合。
103 public const string MkCol = "MKCOL";
104 //
105 // 摘要:
106 // 表示一个 HTTP POST 协议方法,该方法用于将新实体作为补充发送到某个 URI。
107 public const string Post = "POST";
108 //
109 // 摘要:
110 // 表示一个 HTTP PUT 协议方法,该方法用于替换 URI 标识的实体。
111 public const string Put = "PUT";
112 }
113 }
114 }
慢慢积累,你的这些代码都是你的财富,可以帮你提高工作效率,勤勤恳恳的干好每件事情,点滴积累,开心编程。