注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

淡忘邻人

二十七,始发愤

 
 
 

日志

 
 
 
 

FTPFactory FTP客户端  

2010-05-20 22:30:04|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

using System;
using
 System.Net;
using
 System.IO;
using
 System.Text;
using
 System.Net.Sockets;
using
 System.Collections;

namespace
 FtpLib
{

 
public class
 FTPFactory
 {

  
private string
 remoteHost,remotePath,remoteUser,remotePass,mes;
  
private int
 remotePort,bytes;
  
private
 Socket clientSocket;

  
private int
 retValue;
  
private
 Boolean debug;
  
private
 Boolean logined;
  
private string
 reply;

  
private static int BLOCK_SIZE = 512
;

  Byte[] buffer 
= new
 Byte[BLOCK_SIZE];
  Encoding ASCII 
=
 Encoding.ASCII;

  
/// <summary>

  
/// 构造函数
  
/// </summary>

  
/// <param name="remHost">远程主机地址</param>
  
/// <param name="remPort">远程端口</param>
  
/// <param name="remPath">远程路径</param>
  
/// <param name="remUser">远程用户</param>
  
/// <param name="remPass">远程用户密码</param>
  
/// <param name="debugFlag">调试标志</param>
  public FTPFactory(string remHost, int remPort, string remPath, string remUser, string remPass, bool debugFlag)
  {
   remoteHost 
=
 remHost;
   remotePort 
=
 remPort;
   remotePath 
=
 remPath;
   remoteUser 
=
 remUser;
   remotePass 
=
 remPass;
   debug 
=
 debugFlag;
   logined 
= false
;
  }

  
/// <summary>

  
/// 远程主机地址
  
/// </summary>

  public string RemoteHost
  {
   
get

   {
    
return this.remoteHost;
   }
   
set

   {
    
this.remoteHost = value;
   }
  }

  
/// <summary>

  
/// 远程端口
  
/// </summary>

  public int RemotePort
  {
   
get

   {
    
return this.remotePort;
   }
   
set

   {
    
this.remotePort = value;
   }
  }

  
/// <summary>

  
/// 远程主机路径
  
/// </summary>

  public string RemotePath
  {
   
get

   {
    
return this.remotePath;
   }
   
set

   {
    
this.remotePath = value;
   }
  }

  
/// <summary>

  
/// 远程用户名
  
/// </summary>

  public string RemoteUser
  {
   
get

   {
    
return this.remoteUser;
   }
   
set

   {
    
this.remoteUser = value;
   }
  }

  
/// <summary>

  
/// 远程用户密码
  
/// </summary>

  public string RemotePass
  {
   
set

   {
    
this.remotePass = value;
   }
  }

  
/// <summary>

  
/// 获得目录列表
  
/// </summary>

  
/// <param name="mask">目录</param>
  
/// <returns>目录集合</returns>
  public string[] getDirList(string mask)
  {
   
if(!
logined)
   {
    login();
   }

   Socket cSocket 
=
 createDataSocket();
   sendCommand(
"LIST " +
 mask);

   
if(!(retValue == 150 || retValue == 125 || retValue == 226
))
   {
    
throw new IOException(reply.Substring(4
));
   }

   mes 
= ""
;

   
while(true
)
   {

    
int bytes = cSocket.Receive(buffer, buffer.Length, 0
);
    mes 
+= ASCII.GetString(buffer, 0
, bytes);

    
if(bytes <
 buffer.Length)
    {
     
break
;
    }
   }

   
char[] seperator = {'\n'
};
   
string[] mess =
 mes.Split(seperator);

   cSocket.Close();

   ArrayList list 
= new
 ArrayList();

   
foreach(string m in
 mess)
   {
    
if (m.StartsWith("d"&& !m.EndsWith(".\r"&& !m.EndsWith("..\r"
))
    {
     
if (!"".Equals(this
.getDirName(m)))
      list.Add(
this
.getDirName(m));
    }
   }

   
string[] dirs = new string
[list.Count];
   
   
for(int i=0;i<dirs.Length;i++
)
   {
    dirs[i] 
=
 list[i].ToString();
   }


   readReply();

   
if(retValue != 226
)
   {
    
throw new IOException(reply.Substring(4
));
   }
   
return
 dirs;
  }

  
/// <summary>

  
/// 获得文件列表
  
/// </summary>

  
/// <param name="mask">目录</param>
  
/// <returns>文件列表</returns>
  public string[] getFileList(string mask)
  {
   
if(!
logined)
   {
    login();
   }

   Socket cSocket 
=
 createDataSocket();
   sendCommand(
"NLST " +
 mask);

   
if (retValue == 550
)
    
return new string[0
];

   
if(!(retValue == 150 || retValue == 125 || retValue == 226
))
   {
    
throw new IOException(reply.Substring(4
));
   }

   mes 
= ""
;

   
while(true
)
   {

    
int bytes = cSocket.Receive(buffer, buffer.Length, 0
);
    mes 
+= ASCII.GetString(buffer, 0
, bytes);

    
if(bytes <
 buffer.Length)
    {
     
break
;
    }
   }

   
char[] seperator = {'\n'
};
   
string[] mess =
 mes.Split(seperator);

   cSocket.Close();
   
   ArrayList list 
= new
 ArrayList();

   
foreach(string m in
 mess)
   {
    
if (!"".Equals(m.Replace("\r",""
)))
     list.Add(m.Replace(
"\r",""
));
   }

   
string[] files = new string
[list.Count];
   
   
for(int i=0;i<files.Length;i++
)
   {
    files[i] 
=
 list[i].ToString();
   }

   readReply();

   
if(retValue != 226
)
   {
    
throw new IOException(reply.Substring(4
));
   }
   
return
 files;

  }

  
/// <summary>

  
/// 获得文件大小
  
/// </summary>

  
/// <param name="fileName">文件名</param>
  
/// <returns></returns>
  public long getFileSize(string fileName)
  {

   
if(!
logined)
   {
    login();
   }

   sendCommand(
"SIZE " +
 fileName);
   
long size=0
;

   
if(retValue == 213
)
   {
    size 
= Int64.Parse(reply.Substring(4
));
   }
   
else

   {
    
throw new IOException(reply.Substring(4));
   }

   
return
 size;

  }

  
/// <summary>

  
/// 登录
  
/// </summary>

  public void login()
  {

   clientSocket 
= new
 Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
   IPEndPoint ep 
= new IPEndPoint(Dns.Resolve(remoteHost).AddressList[0
], remotePort);

   
try

   {
    clientSocket.Connect(ep);
   }
   
catch(Exception)
   {
    
throw new IOException("Couldn't connect to remote server"
);
   }

   readReply();
   
if(retValue != 220
)
   {
    close();
    
throw new IOException(reply.Substring(4
));
   }
   
if
(debug)
    Console.WriteLine(
"USER "+
remoteUser);

   sendCommand(
"USER "+
remoteUser);

   
if!(retValue == 331 || retValue == 230
) )
   {
    cleanup();
    
throw new IOException(reply.Substring(4
));
   }

   
if( retValue != 230
 )
   {
    
if
(debug)
     Console.WriteLine(
"PASS xxx"
);

    sendCommand(
"PASS "+
remotePass);
    
if!(retValue == 230 || retValue == 202
) )
    {
     cleanup();
     
throw new IOException(reply.Substring(4
));
    }
   }

   logined 
= true
;
   Console.WriteLine(
"Connected to "+
remoteHost);

   chdir(remotePath);

  }


  
/// <summary>

  
/// 设置模式
  
/// </summary>

  
/// <param name="mode">模式</param>
  
/// <remarks>mode为True:Binary模式, mode为False:Ascii模式</remarks>
  public void setBinaryMode(Boolean mode)
  {
   
if
(mode)
   {
    sendCommand(
"TYPE I"
);
   }
   
else

   {
    sendCommand(
"TYPE A");
   }
   
if (retValue != 200
)
   {
    
throw new IOException(reply.Substring(4
));
   }
  }


  
/// <summary>

  
/// 下载文件
  
/// </summary>

  
/// <param name="remFileName">远程文件名</param>
  public void download(string remFileName)
  {
   download(remFileName,
"",false
);
  }

  
/// <summary>

  
/// 下载文件
  
/// </summary>

  
/// <param name="remFileName">远程文件名</param>
  
/// <param name="resume">摘要标志</param>
  public void download(string remFileName,Boolean resume)
  {
   download(remFileName,
""
,resume);
  }

  
/// <summary>

  
/// 下载文件
  
/// </summary>

  
/// <param name="remFileName">远程文件名</param>
  
/// <param name="locFileName">本地文件名</param>
  
/// <remarks>本地文件被创建或者覆盖,但是目录必须存在.</remarks>
  public void download(string remFileName,string locFileName)
  {
   download(remFileName,locFileName,
false
);
  }

  
/// <summary>

  
/// 下载文件
  
/// </summary>

  
/// <param name="remFileName">远程文件名</param>
  
/// <param name="locFileName">本地文件名</param>
  
/// <param name="resume">摘要标志</param>
  
/// <remarks>本地文件被创建或者覆盖,但是目录必须存在.</remarks>
  public void download(string remFileName,string locFileName,Boolean resume)
  {
   
if(!
logined)
   {
    login();
   }

   setBinaryMode(
true
);

   Console.WriteLine(
"Downloading file "+remFileName+" from "+remoteHost + "/"+
remotePath);

   
if (locFileName.Equals(""
))
   {
    locFileName 
=
 remFileName;
   }

   
if(!
File.Exists(locFileName))
   {
    Stream st 
=
 File.Create(locFileName);
    st.Close();
   }

   FileStream output 
= new
 
    FileStream(locFileName,FileMode.Open);

   Socket cSocket 
=
 createDataSocket();

   
long offset = 0
;

   
if
(resume)
   {

    offset 
=
 output.Length;

    
if(offset > 0
 )
    {
     sendCommand(
"REST "+
offset);
     
if(retValue != 350
)
     {
      
//
throw new IOException(reply.Substring(4));
      
//Some servers may not support resuming.

      offset = 0;
     }
    }

    
if(offset > 0
)
    {
     
if
(debug)
     {
      Console.WriteLine(
"seeking to " +
 offset);
     }
     
long npos =
 output.Seek(offset,SeekOrigin.Begin);
     Console.WriteLine(
"new pos="+
npos);
    }
   }

   sendCommand(
"RETR " +
 remFileName);

   
if(!(retValue == 150 || retValue == 125 || retValue == 226
))
   {
    
throw new IOException(reply.Substring(4
));
   }

   
while(true
)
   {

    bytes 
= cSocket.Receive(buffer, buffer.Length, 0
);
    output.Write(buffer,
0
,bytes);

    
if(bytes <= 0
)
    {
     
break
;
    }
   }

   output.Close();
   
if
 (cSocket.Connected)
   {
    cSocket.Close();
   }

   Console.WriteLine(
""
);

   readReply();

   
if!(retValue == 226 || retValue == 250
) )
   {
    
throw new IOException(reply.Substring(4
));
   }

  }

  
/// <summary>

  
/// 上传文件
  
/// </summary>

  
/// <param name="fileName">文件名</param>
  public void upload(string fileName)
  {
   upload(fileName,
false
);
  } 

  
/// <summary>

  
/// 上传文件
  
/// </summary>

  
/// <param name="fileName">文件名</param>
  
/// <param name="resume">摘要标志</param>
  public void upload(string fileName,Boolean resume)
  {

   
if(!
logined)
   {
    login();
   }

   Socket cSocket 
=
 createDataSocket();
   
long offset=0
;

   
if
(resume)
   {

    
try

    {

     setBinaryMode(
true);
     offset 
=
 getFileSize(fileName);

    }
    
catch
(Exception)
    {
     offset 
= 0
;
    }
   }

   
if(offset > 0
 )
   {
    sendCommand(
"REST " +
 offset);
    
if(retValue != 350
)
    {
     
//
throw new IOException(reply.Substring(4));
     
//Remote server may not support resuming.

     offset = 0;
    }
   }

   sendCommand(
"STOR "+
Path.GetFileName(fileName));

   
if!(retValue == 125 || retValue == 150
) )
   {
    
throw new IOException(reply.Substring(4
));
   }

   
// open input stream to read source file

   FileStream input = new 
    FileStream(fileName,FileMode.Open);

   
if(offset != 0
)
   {

    
if
(debug)
    {
     Console.WriteLine(
"seeking to " +
 offset);
    }
    input.Seek(offset,SeekOrigin.Begin);
   }

   Console.WriteLine(
"Uploading file "+fileName+" to "+
remotePath);

   
while ((bytes = input.Read(buffer,0,buffer.Length)) > 0
)
   {

    cSocket.Send(buffer, bytes, 
0
);

   }
   input.Close();

   Console.WriteLine(
""
);

   
if
 (cSocket.Connected)
   {
    cSocket.Close();
   }

   readReply();
   
if!(retValue == 226 || retValue == 250
) )
   {
    
throw new IOException(reply.Substring(4
));
   }
  }

  
/// <summary>

  
/// 删除远程文件
  
/// </summary>

  
/// <param name="fileName">文件名</param>
  public void deleteRemoteFile(string fileName)
  {

   
if(!
logined)
   {
    login();
   }

   sendCommand(
"DELE "+
fileName);

   
if(retValue != 250
)
   {
    
throw new IOException(reply.Substring(4
));
   }

  }

  
/// <summary>

  
/// 重命名远程文件
  
/// </summary>

  
/// <param name="oldFileName">原始文件名</param>
  
/// <param name="newFileName">新文件名</param>
  public void renameRemoteFile(string oldFileName,string newFileName)
  {

   
if(!
logined)
   {
    login();
   }

   sendCommand(
"RNFR "+
oldFileName);

   
if(retValue != 350
)
   {
    
throw new IOException(reply.Substring(4
));
   }

   
//
  known problem
   
//
  rnto will not take care of existing file.
   
//  i.e. It will overwrite if newFileName exist

   sendCommand("RNTO "+newFileName);
   
if(retValue != 250
)
   {
    
throw new IOException(reply.Substring(4
));
   }

  }

  
/// <summary>

  
/// 创建目录
  
/// </summary>

  
/// <param name="dirName">目录名</param>
  public void mkdir(string dirName)
  {

   
if(!
logined)
   {
    login();
   }

   sendCommand(
"MKD "+
dirName);

   
if(retValue != 250
)
   {
    
throw new IOException(reply.Substring(4
));
   }

  }

  
/// <summary>

  
/// 删除目录
  
/// </summary>

  
/// <param name="dirName">目录名</param>
  public void rmdir(string dirName)
  {

   
if(!
logined)
   {
    login();
   }

   sendCommand(
"RMD "+
dirName);

   
if(retValue != 250
)
   {
    
throw new IOException(reply.Substring(4
));
   }

  }

  
/// <summary>

  
/// 改变当前工作路径
  
/// </summary>

  
/// <param name="dirName">目录名称</param>
  public void chdir(string dirName)
  {
   
if(dirName.Equals("."
))
   {
    
return
;
   }
   
if(!
logined)
   {
    login();
   }

   sendCommand(
"CWD "+
dirName);

   
if(retValue != 250
)
   {
    
throw new IOException(reply.Substring(4
));
   }

   
this.remotePath =
 dirName;

   Console.WriteLine(
"Current directory is "+
remotePath);

  }

  
/// <summary>

  
/// 关闭Ftp连接
  
/// </summary>

  public void close()
  {

   
if( clientSocket != null
 )
   {
    sendCommand(
"QUIT"
);
   }

   cleanup();
   Console.WriteLine(
"Closing"
);
  }

  
/// <summary>

  
/// 设置调试模式
  
/// </summary>

  
/// <param name="debug">调式模式</param>
  public void setDebug(Boolean debug)
  {
   
this.debug =
 debug;
  }

  
private void
 readReply()
  {
   mes 
= ""
;
   reply 
=
 readLine();
   retValue 
= Int32.Parse(reply.Substring(0,3
));
  }

  
private void
 cleanup()
  {
   
if(clientSocket!=null
)
   {
    clientSocket.Close();
    clientSocket 
= null
;
   }
   logined 
= false
;
  }

  
private string
 readLine()
  {

   
while(true
)
   {
    bytes 
= clientSocket.Receive(buffer, buffer.Length, 0
);
    mes 
+= ASCII.GetString(buffer, 0
, bytes);
    
if(bytes <
 buffer.Length)
    {
     
break
;
    }
   }

   
char[] seperator = {'\n'
};
   
string[] mess =
 mes.Split(seperator);

   
if(mes.Length > 2
)
   {
    mes 
= mess[mess.Length-2
];
   }
   
else

   {
    mes 
= mess[0];
   }

   
if(!mes.Substring(3,1).Equals(" "
))
   {
    
return
 readLine();
   }

   
if
(debug)
   {
    
for(int k=0;k < mess.Length-1;k++
)
    {
     Console.WriteLine(mess[k]);
    }
   }
   
return
 mes;
  }

  
private void
 sendCommand(String command)
  {
   Byte[] cmdBytes 
=
 
    Encoding.ASCII.GetBytes((command
+"\r\n"
).ToCharArray());
   clientSocket.Send(cmdBytes, cmdBytes.Length, 
0
);
   readReply();
  }

  
private
 Socket createDataSocket()
  {

   sendCommand(
"PASV"
);

   
if(retValue != 227
)
   {
    
throw new IOException(reply.Substring(4
));
   }

   
int index1 = reply.IndexOf('('
);
   
int index2 = reply.IndexOf(')'
);
   
string ipData =
 
    reply.Substring(index1
+1,index2-index1-1
);
   
int[] parts = new int[6
];

   
int len =
 ipData.Length;
   
int partCount = 0
;
   
string buf=""
;

   
for (int i = 0; i < len && partCount <= 6; i++
)
   {

    
char ch = Char.Parse(ipData.Substring(i,1
));
    
if
 (Char.IsDigit(ch))
     buf
+=
ch;
    
else if (ch != ','
)
    {
     
throw new IOException("Malformed PASV reply: " +
 
      reply);
    }

    
if (ch == ',' || i+1 ==
 len)
    {

     
try

     {
      parts[partCount
++= Int32.Parse(buf);
      buf
=""
;
     }
     
catch
 (Exception)
     {
      
throw new IOException("Malformed PASV reply: " +
 
       reply);
     }
    }
   }

   
string ipAddress = parts[0+ "."+ parts[1]+ "." +

    parts[
2+ "." + parts[3];

   
int port = (parts[4<< 8+ parts[5
];

   Socket s 
= new
 
    Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
   IPEndPoint ep 
= new
 
    IPEndPoint(Dns.Resolve(ipAddress).AddressList[
0
], port);

   
try

   {
    s.Connect(ep);
   }
   
catch(Exception)
   {
    
throw new IOException("Can't connect to remote server"
);
   }

   
return
 s;
  }


  
private string getDirName(string
 mess)
  {
   
string dirName = string.Empty;  //没完

}
  评论这张
 
阅读(464)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017