用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心编程技巧编程其他

FTP Client library in C#

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-03-16 19:37:55
这是个用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 = "ftpclient@ospreyindia.com";
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 = {''};
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 = {''};
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+"").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);
}
}
}

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:7,000.00000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号