📄 fclient.cpp
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 类:CFTPClient
//
// 描述:
// 主要实现文件的上传和下载并能够获取服务端文件的列表进行解析.同时他也存在一些不足的地方,希望大家给
// 改正.
//
// 联系方式:
// E-Mail:lihualoveyou1983@163.com
//
// QQ:61915319
//
//
//
//
//
// 吴庆民 2005.5.4
///////////////////////////////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include ".\fclient.h"
#include "ftpclientdlg.h"
CFTPClient::CFTPClient(void)
{
}
CFTPClient::~CFTPClient(void)
{
}
CFTPClient::FtpCommand (CString strCommand)
{
if (strCommand!="" && !this->WriteStr (strCommand)) return FALSE;
//当发送一个消息之后,服务器会对消息有一个确认
if ((!this->ReadStr ())|| this->m_fc !=2) return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:BOOL CFTPClient::LogOnToserver ()
//
// 描述:
// 这个函数用于登录到FTP服务器,在这个函数没有对系统的防火墙作进一步分析,读者可以进一步扩展它的功能
//
//
// 参数:
// -strHostname 登录的主机名
// -nHostPort 主机端口
// -strUserName 用户名
// -strPassword 用户密码
// 返回:
// -BOOL 成功返回 TRUE 否则返回 FALSE
//
// 吴庆民 2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::LogOnToserver (CString strHostname,int nHostPort,CString strUserName,CString strPassword)
{
if (!this->OpenControlChannel (strHostname,21)) return FALSE;
if(!this->ReadStr ()) return FALSE;
this->SetMessage (this->m_strMsg );
//发送一个空消息
//if (!this->FtpCommand ("")) return FALSE;
CString temp;
temp = "USER " + strUserName + "\n\r";
//发送用户名
if (!this->WriteStr (temp))
{
return FALSE;
}
if (!this->ReadStr ()) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this->SetMessage (this->m_strMsg );
//发送密码
temp = "PASS " + strPassword + "\n\r";
if (!this->WriteStr (temp)) return FALSE;
if (!this->ReadStr ()) return FALSE;
//if (!this->ReadStr ()) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this->SetMessage (this->m_strMsg );
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:BOOL CFTPClient::WriteStr ()
//
// 描述:
// 这个函数主要是用来向服务器发送命令
//
//
// 参数:
// -strOutPut 发送的命令内容,具本格式参考FTP相关资料
// 返回:
// -BOOL 成功返回 TRUE 否则返回 FALSE
//
// 吴庆民 2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::WriteStr (CString strOutPut)
{
//try
//{
this->m_pTxarch->WriteString (strOutPut);
//把数据写入文档
this->m_pTxarch->Flush ();
//}
//catch (CException,e)
//{
//
// return FALSE;
//}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:BOOL CFTPClient::ReadStr ()
//
// 描述:
//
// 读取服务器返回的信息
//
// 参数:
// -无
// 返回:
// -BOOL 成功返回 TRUE 否则返回 FALSE
//
// 吴庆民 2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::ReadStr ()
{
int reCode;
if (!this->ReadStr2 ()) return FALSE;
if ((this->m_strMsg.GetLength () < 4) || (this->m_strMsg.GetAt (3) != '-')) return TRUE; //服务器只发送了一条消息
reCode = atol(this->m_strMsg );
while (1)
{
if ((this->m_strMsg.GetLength () >3 )&&(this->m_strMsg.GetAt (3) != '-') && atol(this->m_strMsg)==reCode)
return TRUE;
if (!this->ReadStr2 ()) return FALSE;
}
//this->m_fc = this->m_strMsg.GetAt (1);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:CFTPClient::OpenControlChannel
//
// 描述:
// 打开一个通道用于传输FTP命令.
//
// 参数:
// -strServerHost 服务端地址
//
// -nServerPort 端口号
//
//
// 返回值:
//
// -BOOL 是否打开通道成功
//
// 吴庆民 2005.5.4
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::OpenControlChannel (CString strServerHost,int nServerPort)
{
//创建CSocket
if (!(this->m_pSocket=new CSocket)) return FALSE;
if (!(this->m_pSocket->Create ())) return FALSE;
//连接服务器
if (!(this->m_pSocket->Connect (strServerHost,nServerPort))) return FALSE;
//创建实例
if (!(this->m_psfSokFile = new CSocketFile (this->m_pSocket ))) return FALSE;
if (!(this->m_pRxarch = new CArchive (this->m_psfSokFile ,CArchive::load ))) return FALSE;
if (!(this->m_pTxarch = new CArchive (this->m_psfSokFile ,CArchive::store ))) return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:CFTPClient::CloseControlChannel ()
//
// 描述:
// 关闭命令传输通道
//
// 参数:
// -无
//
//
//
//
// 返回值:
//
// -无
//
// 吴庆民 2005.5.4
///////////////////////////////////////////////////////////////////////////////////////////////////////
void CFTPClient::CloseControlChannel ()
{
delete this->m_pSocket ;
delete this->m_pRxarch ;
delete this->m_pTxarch ;
delete this->m_psfSokFile ;
}
BOOL CFTPClient::ReadStr2 ()
{
if(!this->m_pRxarch->ReadString (this->m_strMsg)) return FALSE;
if (this->m_strMsg.GetLength() >0)
{
m_fc= m_strMsg.GetAt(0) ;
}
return TRUE ;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 函数:BOOL CFTPClient::List ()
//
// 描述:
// 列出当前文件信息,在下面几个函数里对信息进行了解析
//
//
// 参数:
// -无
// 返回:
// -BOOL 成功返回 TRUE 否则返回 FALSE
//
// 吴庆民 2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::List ()
{
CSocket sServ;//用于侦听
CAsyncSocket asDataChannel; //用于接收数据
CString strCommand;//发送的命令]
CString strAdress;//本机地址
UINT nListenPort ; //侦听的端口号
//开始侦听 这个要在发送命令之前,否则出错
if (!(sServ.Create (0,SOCK_STREAM,NULL))||(!sServ.Listen ()))
{
return FALSE;
}
sServ.GetSockName(strAdress,nListenPort);
UINT temp;
//在连接时设置了用户的IP,因此要从这里得到你现在作用的IP地址,而不要从注释的方式得到
//sServ.GetSockName(strAdress,nListenPort);
this->m_pSocket->GetSockName (strAdress,temp);
int i;
//strAdress = "127.0.0.1";
while(1)
{
if ((i = strAdress.Find ("."))== -1) break;
strAdress.SetAt(i,',');
}
strAdress.Format (strAdress+",%d,%d",nListenPort/256,nListenPort%256);
//::AfxMessageBox (strAdress);
strCommand = "PORT " + strAdress ;
strCommand += "\n\r";
if (!this->WriteStr(strCommand)) return FALSE;
//if (!this->WriteStr ("")) return FALSE;
//在这个过程中没有命令确认反回
strCommand = "TYPE I \n\r" ;
if (!(this->WriteStr (strCommand))) return FALSE;
if (!(this->ReadStr ())) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this ->SetMessage (this->m_strMsg );
if (!(this->ReadStr ())) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this->SetMessage (this->m_strMsg );
strCommand = "LIST \n\r";
if (!(this->WriteStr (strCommand))) return FALSE;
if (!(this->ReadStr ())) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this ->SetMessage (this->m_strMsg );
if (!(this->ReadStr ())) return FALSE;
//::AfxMessageBox (this->m_strMsg );
this->SetMessage (this->m_strMsg );
//接受服务器的联接
if (!sServ.Accept (asDataChannel ))
return FALSE;
DWORD lpArgument = 0;
int num,sum;
//定义缓冲区的大小'
const int BUFSIZE = 4096;
//清空缓冲区
this->m_btBuf.RemoveAll ();
this->m_btBuf.SetSize (BUFSIZE);
//获取数据
if ((!asDataChannel.AsyncSelect (0))||(!asDataChannel.IOCtl (FIONBIO,&lpArgument)))
{
return FALSE;
}
//获取数据
sum = 0;
while (1)//在这里没有循环结束条件
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -