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

#pragma hdrstop

#include "FTPClient.h"

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

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

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

    m_pDataSock=new CSocket();
    //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;      //Буфер для отправляемых данных
    char InBuf[10000];	//Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Логин
    OutBuf="USER "+_User+"\r\n";
    m_pStream->Write(OutBuf.c_str(),OutBuf.size());

	InLen=m_pStream->Read(InBuf,sizeof(InBuf));
    *(InBuf+InLen)='\0';
    cout << InBuf;
    if(strncmp(InBuf,"331 ",4))
    {
        cout << "##Login incorrect" << endl;
        return false;
    }
    cout << "##Login OK" << endl;

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

    //Переходим в пассивный режим
    OutBuf="PASV\r\n";
    m_pStream->Write(OutBuf.c_str(),OutBuf.size());
    InLen=m_pStream->Read(InBuf,sizeof(InBuf));
    *(InBuf+InLen)='\0';
    cout << InBuf;
    if(strncmp(InBuf,"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,'(');
    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]);

	if(!m_pDataSock->Create())    
	{
		cout << "##Couldn't create socket" << endl;
		return false;
	}

	//Назначаем адрес и порт для сокета данных
    if(!m_pDataSock->Connect(CString(DataIP),(Port[0]<<8)+Port[1]))
	{
		cout << "##Couldn't connect to server" << endl;
		m_pDataSock->Close();
		return false;
	}    

    //Создаем поток для приема/отправки данных
    m_pDataStream=new CSocketFile(m_pDataSock);

    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;      //Буфер для отправляемых данных
    char InBuf[10000];	//Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

	if(!m_pSock->Create())
	{
        cout << "##Couldn't create socket" << endl;
		return false;
	}

    //Создаем поток для приема/отправки команд
    m_pStream=new CSocketFile(m_pSock);

	//Назначаем адрес и порт
    if(!m_pSock->Connect(CString(_Address.c_str()),_Port))
	{
		cout << "##Couldn't connect to server" << endl;
		m_pSock->Close();
		return false;
	}

	//Получаем ответ сервера на подключение
	InLen=m_pStream->Read(InBuf,sizeof(InBuf));
    *(InBuf+InLen)='\0';
    cout << InBuf;
    if(strncmp(InBuf,"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;      //Буфер для отправляемых данных
    char InBuf[10000];  //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    //Выход
    OutBuf="QUIT\r\n";
	m_pStream->Write(OutBuf.c_str(),OutBuf.size());

		InLen=m_pStream->Read(InBuf,sizeof(InBuf));
        *(InBuf+InLen)='\0';
        cout << InBuf;
        if(strncmp(InBuf,"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;      //Буфер для отправляемых данных
    char InBuf[10000];  //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    bool Res=false;

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

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

    if(!OpenDataConnection())
        return false;

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

        CloseDataConnection();

        //Получаем подтверждение
        InLen=m_pStream->Read(InBuf,sizeof(InBuf));
        *(InBuf+InLen)='\0';
        cout << InBuf;
        if(!strncmp(InBuf,"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;      //Буфер для отправляемых данных
    char InBuf[10000];  //Буфер для принимаемых данных
    int InLen;          //Длина полученных данных

    if(!OpenDataConnection())
        return false;

    //Получение файла
    OutBuf="RETR "+_Name+"\r\n";
    m_pStream->Write(OutBuf.c_str(),OutBuf.size());
    InLen=m_pStream->Read(InBuf,sizeof(InBuf));
    *(InBuf+InLen)='\0';
    cout << InBuf;
    if(!strncmp(InBuf,"150 ",4))
    {
        //Получаем данные
        InLen=m_pDataStream->Read(InBuf,sizeof(InBuf));
        *(InBuf+InLen)='\0';
        cout << InBuf;

        CloseDataConnection();

        //Получаем подтверждение
        InLen=m_pStream->Read(InBuf,sizeof(InBuf));
        *(InBuf+InLen)='\0';
        cout << InBuf;
        if(!strncmp(InBuf,"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;
    }
}
//---------------------------------------------------------------------------*/
Соседние файлы в папке TCPClient