本文档使用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 图片上传和下载
![](https://i-blog.csdnimg.cn/blog_migrate/5de636b17c53e7bb0b0bb2a3a89c8cea.png)
2.2 目录创建和删除
这个方法今天刚好用上了,折腾了一会,才搞定的。
3.调用代码参考
由于这个帮助类不是静态的,所以需要实例化
string userName = "xxx"; string password = "xxx"; var ftp = new FTPClientHelper("xxx", ".", userName, password, 1021);
下面还是调用常用的方法,就可以了,因为账号、密码、服务器的IP地址都被我用“xxx”代替了,所以大家自己改下,还有ftp默认端口号是:21,如果有变动还是需要自己改下的。
4.FTPClientHelper下载
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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常用的命令
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
慢慢积累,你的这些代码都是你的财富,可以帮你提高工作效率,勤勤恳恳的干好每件事情,点滴积累,开心编程。