Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:seti_2semestr / Лабораторные работы / ЛР_7 / Samples / TCP / CPPBuilder / FTPClient
.cpp//---------------------------------------------------------------------------
#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