|
|
FTP Client library in C# |
|
|
作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站 |
这是个用C#写的FTP客户端库文件,可编译成DLL使用, 支持所有的FTP命令、文件上下传,
/* FTPFactory.cs Better view with tab space=4 use the following line to compile csc /target:library /out:FTPLib.dll /r:System.Net.DLL FTPFactory.cs */
using System; using System.Net; using System.IO; using System.Text; using System.Net.Sockets;
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;
public FTPFactory() {
remoteHost = "localhost"; remotePath = "."; remoteUser = "anonymous"; remotePass = "[email protected]"; remotePort = 21; debug = false; logined = false;
} public void setRemoteHost(string remoteHost) { this.remoteHost = remoteHost; } public string getRemoteHost() { return remoteHost; } public void setRemotePort(int remotePort) { this.remotePort = remotePort; } public int getRemotePort() { return remotePort; } public void setRemotePath(string remotePath) { this.remotePath = remotePath; } public string getRemotePath() { return remotePath; } public void setRemoteUser(string remoteUser) { this.remoteUser = remoteUser; } public void setRemotePass(string remotePass) { this.remotePass = remotePass; } public string[] getFileList(string mask) {
if(!logined) { login(); }
Socket cSocket = createDataSocket();
sendCommand("NLST " + mask);
if(!(retValue == 150 || retValue == 125)) { 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();
readReply(); if(retValue != 226) { throw new IOException(reply.Substring(4)); } return mess;
} public long getFileSize(string fileName) {
if(!logined) { login(); }
sendCommand("SIZE " + fileName); long size=0;
if(retValue == 213) { size = reply.Substring(4).ToInt64(); }else { throw new IOException(reply.Substring(4)); } return size;
} public void login() {
clientSocket = new Socket(AddressFamily.AfINet,SocketType.SockStream,ProtocolType.ProtTCP); IPEndPoint ep = new IPEndPoint(DNS.Resolve(remoteHost), remotePort); int i = clientSocket.Connect(ep); if( i != 0 ) { 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);
} public void setBinaryMode(Boolean mode) {
if(mode) { sendCommand("TYPE I"); }else { sendCommand("TYPE A"); } if (retValue != 200) { throw new IOException(reply.Substring(4)); } } public void download(string fileName) { download(fileName,false); } public void download(string fileName,Boolean resume) {
if(!logined) { login(); }
setBinaryMode(true); long totalSize=0; try{ totalSize = getFileSize(fileName); }catch(Exception) { throw new Exception("File Not Found "+fileName); }
Console.WriteLine("Downloading file "+fileName+" from "+remoteHost + "/"+remotePath);
if(!File.FileExists(fileName)) { Stream st = File.Create(fileName); st.Close(); }
FileStream output = new FileStream(fileName,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)); //Server 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 " + fileName);
if(!(retValue == 150 || retValue == 125)) { throw new IOException(reply.Substring(4)); }
float iCnt = 0; float per = 0, oldPer = 1;
while(true) {
bytes = cSocket.Receive(buffer, buffer.Length, 0); output.Write(buffer,0,bytes);
// Showing the progress. 1..50 iCnt += bytes; per = (int) ( (iCnt / totalSize) * 100 ); if( per != oldPer && per % 2 == 0 ) { Console.Write("."); oldPer = per; }
if(bytes < buffer.Length) { break; } }
output.Close(); cSocket.Close(); Console.WriteLine("");
readReply();
if( !(retValue == 226 || retValue == 250) ) { throw new IOException(reply.Substring(4)); }
} public void upload(string fileName) { upload(fileName,false); } 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 "+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); }
//for progress bar long totalSize = input.Length - offset; float iCnt = 0; int per = 0, oldPer = 1; Console.WriteLine("Uploading file "+fileName+" to "+remotePath);
while ((bytes = input.Read(buffer,0,buffer.Length)) > 0) {
cSocket.Send(buffer, bytes, 0);
// Showing the progress. 1..50 iCnt += bytes; per = (int) ( (iCnt / totalSize) * 100 ); if( per != oldPer && per % 2 == 0 ) { Console.Write("."); oldPer = per; } } input.Close();
Console.WriteLine("");
cSocket.Close();
readReply(); if( !(retValue == 226 || retValue == 250) ) { throw new IOException(reply.Substring(4)); } } public void deleteRemoteFile(string fileName) {
if(!logined) { login(); }
sendCommand("DELE "+fileName);
if(retValue != 250) { throw new IOException(reply.Substring(4)); }
} 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)); }
} public void mkdir(string dirName) {
if(!logined) { login(); }
sendCommand("MKD "+dirName);
if(retValue != 250) { throw new IOException(reply.Substring(4)); }
} public void rmdir(string dirName) {
if(!logined) { login(); }
sendCommand("RMD "+dirName);
if(retValue != 250) { throw new IOException(reply.Substring(4)); }
} 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);
} public void close() { if( clientSocket != null ) { sendCommand("QUIT"); } cleanup(); Console.WriteLine("Closing..."); } public void setDebug(Boolean debug) { this.debug = debug; } private void readReply() { mes = ""; reply = readLine(); retValue = reply.Substring(0,3).ToInt32(); } 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 = ipData.Substring(i,1).ToChar(); if (Char.IsDigit(ch)) buf+=ch; else if (ch != ',') { throw new IOException("Malformed PASV reply: " + reply); }
if (ch == ',' || i+1 == len) { try { parts[partCount++] = buf.ToInt32(); 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.AfINet,SocketType.SockStream,ProtocolType.ProtTCP); IPEndPoint ep = new IPEndPoint(DNS.Resolve(ipAddress), port);
int sucess = s.Connect(ep);
if( sucess != 0 ) { throw new IOException("Can't connect to remote server"); }
return s; }
} }
Following is the listing of a test program which uses this library
/*
File : Test.cs Better view with tab space=4 use the following line to compile csc.exe /t:exe /r:System.DLL /r:System.Net.DLL /r:FTPLib.dll /out:"Test.exe" "Test.cs"
*/ using System; using FtpLib;
public class Test {
public static void Main() {
try {
Console.WriteLine("Starting...");
FTPFactory ff = new FTPFactory(); ff.setDebug(true); ff.setRemoteHost("192.168.10.19"); ff.setRemoteUser("jaimon"); ff.setRemotePass("mathew"); ff.login();
string[] fileNames = ff.getFileList("*.*"); for(int i=0;i < fileNames.Length;i++) { Console.WriteLine(fileNames[i]); } ff.download("Readme.zip",true); ff.close();
}catch(Exception e) { Console.WriteLine("Caught Error :"+e.Message); } } }

|
|
相关文章:相关软件: |
|