⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fclient.cpp

📁 ftp协议的解析和实现源代码.介绍了FTP协议的实现原理.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  类: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 + -