Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
19
Добавлен:
11.05.2015
Размер:
11.77 Кб
Скачать
//---------------------------------------------------------------------------


#pragma hdrstop

#include "FTPClient.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

//---------------------------------------------------------------------------
CFTPClient::CFTPClient(void)
{
    m_Timeout=20000;

    m_pSock=new TClientSocket(NULL);
    m_pSock->ClientType=ctBlocking;
    m_pStream=NULL;

    m_pDataSock=new TClientSocket(NULL);
    m_pDataSock->ClientType=ctBlocking;
    m_pDataStream=NULL;
}
//---------------------------------------------------------------------------
CFTPClient::~CFTPClient(void)
{
    delete m_pDataSock;
    delete m_pSock;
}
//---------------------------------------------------------------------------
bool CFTPClient::Login(const string& _User,const string& _Pass)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    //Логин
    OutBuf="USER "+_User+"\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
        return false;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(strncmp(InBuf.c_str(),"331 ",4))
    {
        cout << "##Login incorrect" << endl;
        return false;
    }
    cout << "##Login OK" << endl;

    //Пароль
    OutBuf="PASS "+_Pass+"\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    bool PassOK=false;
    while(1)
    {
        if(!m_pStream->WaitForData(m_Timeout))
        {
            cout << "##Server response timeout" << endl;
            break;
        }
        InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();
        if(strstr(InBuf.begin(),"230 "))
        {
            PassOK=true;
            break;
        }
    }
    if(PassOK)
    {
        cout << "##Password OK" << endl;
        return true;
    }
    cout << "##Password incorrect" << endl;
    return false;
}
//---------------------------------------------------------------------------
bool CFTPClient::OpenDataConnection(void)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    //Переходим в пассивный режим
    OutBuf="PASV\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(strncmp(InBuf.c_str(),"227 ",4))
    {
        cout << "##Error entering passive mode" << endl;
        return false;
    }
    cout << "##Passive mode OK" << endl;
    int IP[4],Port[2];
    const char* Pos=strchr(InBuf.c_str(),'(');
    if(!Pos)
    {
        cout << "##Couldn't parse server string" << endl;
        return false;
    }
    sscanf(Pos,"(%d,%d,%d,%d,%d,%d)",IP+0,IP+1,IP+2,IP+3,Port+0,Port+1);

    char DataIP[20];
    sprintf(DataIP,"%d.%d.%d.%d",IP[0],IP[1],IP[2],IP[3]);

    //Назначаем адрес и порт для сокета данных
    m_pDataSock->Host=DataIP;
    m_pDataSock->Port=(Port[0]<<8)+Port[1];
    m_pDataSock->Open();

    //Создаем поток для приема/отправки данных
    m_pDataStream=new TWinSocketStream(m_pDataSock->Socket,10000);

    return true;
}
//---------------------------------------------------------------------------
void CFTPClient::CloseDataConnection(void)
{
    delete m_pDataStream;
    m_pDataStream=NULL;
    m_pDataSock->Close();
}
//---------------------------------------------------------------------------
bool CFTPClient::ConnectServer(const string& _Address,const string& _User,
        const string& _Pass,UINT _Port)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    //Назначаем адрес и порт
    m_pSock->Host=_Address.c_str();
    m_pSock->Port=_Port;
    m_pSock->Open();

    //Создаем поток для приема/отправки команд
    m_pStream=new TWinSocketStream(m_pSock->Socket,10000);

    //Получаем ответ сервера на подключение
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
        return false;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(strncmp(InBuf.c_str(),"220 ",4))
    {
        cout << "##Couldn't connect to FTP Server" << endl;
        return false;
    }
    cout << "##Connection OK" << endl;

    if(!Login(_User,_Pass))
    {
        delete m_pStream;
        m_pStream=NULL;
        m_pSock->Close();
        return false;
    }

    return true;
}
//---------------------------------------------------------------------------
void CFTPClient::DisconnectServer(void)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    //Выход
    OutBuf="QUIT\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
    }
    else
    {
        InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();
        if(strncmp(InBuf.c_str(),"221 ",4))
            cout << "##Quit incorrect" << endl;
        else
            cout << "##Quit OK" << endl;
    }

    delete m_pStream;
    m_pStream=NULL;
    m_pSock->Close();
}
//---------------------------------------------------------------------------
bool CFTPClient::ChangeDirectory(const string& _Dir)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    bool Res=false;

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    //Изменение директории
    OutBuf="CWD "+_Dir+"\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
        return false;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(!strncmp(InBuf.c_str(),"250 ",4))
    {
        cout << "##Change dir OK" << endl;
        Res=true;
    }
    else
    {
        cout << "##Change dir failed" << endl;
    }

    //Текущая директория
    OutBuf="PWD\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
    }
    else
    {
        InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();
        if(!strncmp(InBuf.c_str(),"257 ",4))
        {
            cout << "##Current dir OK" << endl;
        }
        else
        {
            cout << "##Current dir failed" << endl;
        }
    }
    return Res;
}
//---------------------------------------------------------------------------
bool CFTPClient::ListDirectory(void)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    if(!OpenDataConnection())
        return false;

    //Содержимое каталога
    OutBuf="LIST\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
        return false;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(!strncmp(InBuf.c_str(),"150 ",4))
    {
        //Получаем данные
        if(!m_pDataStream->WaitForData(m_Timeout))
        {
            cout << "##Server response timeout" << endl;
            return false;
        }
        InLen=m_pDataStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();

        CloseDataConnection();

        //Получаем подтверждение
        if(!m_pStream->WaitForData(m_Timeout))
        {
            cout << "##Server response timeout" << endl;
            return false;
        }
        InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();
        if(!strncmp(InBuf.c_str(),"226 ",4))
        {
            cout << "##List dir OK" << endl;
            return true;
        }
        else
        {
            cout << "##List dir failed" << endl;
            return false;
        }
    }
    else
    {
        cout << "##List dir failed" << endl;
        return false;
    }
}
//---------------------------------------------------------------------------
bool CFTPClient::RetrieveFile(const string& _Name,const string& _SaveTo)
{
    string OutBuf;      //Буфер для отправляемых данных
    string InBuf;       //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Резервируем память под входной буфер
    InBuf.reserve(10000);

    if(!OpenDataConnection())
        return false;

    //Получение файла
    OutBuf="RETR "+_Name+"\r\n";
    m_pStream->Write(OutBuf.begin(),OutBuf.size());
    if(!m_pStream->WaitForData(m_Timeout))
    {
        cout << "##Server response timeout" << endl;
        return false;
    }
    InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
    *(InBuf.begin()+InLen)='\0';
    cout << InBuf.c_str();
    if(!strncmp(InBuf.c_str(),"150 ",4))
    {
        //Получаем данные
        if(!m_pDataStream->WaitForData(m_Timeout))
        {
            cout << "##Server response timeout" << endl;
            return false;
        }
        InLen=m_pDataStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();

        CloseDataConnection();

        //Получаем подтверждение
        if(!m_pStream->WaitForData(m_Timeout))
        {
            cout << "##Server response timeout" << endl;
            return false;
        }
        InLen=m_pStream->Read(InBuf.begin(),InBuf.capacity());
        *(InBuf.begin()+InLen)='\0';
        cout << InBuf.c_str();
        if(!strncmp(InBuf.c_str(),"226 ",4))
        {
            cout << "##Retrieve file OK" << endl;
            return true;
        }
        else
        {
            cout << "##Retrieve file failed" << endl;
            return false;
        }
    }
    else
    {
        cout << "##Retrieve file failed" << endl;
        return false;
    }
}
//---------------------------------------------------------------------------
Соседние файлы в папке CPPBuilder