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

📄 fclient.cpp

📁 ftp协议的解析和实现源代码.介绍了FTP协议的实现原理.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		TRY
		{
			if (!(num = asDataChannel.Receive (this->m_btBuf.GetData() + sum,BUFSIZE,0)||(num == SOCKET_ERROR)))
				break;
		
			//sleep(0);
			sum += num;
			this->m_btBuf.SetSize (sum+BUFSIZE);
		}
		CATCH(CException,e)
		{
			return FALSE;
		}
		END_CATCH
	}
	asDataChannel.Close ();
	//::AfxMessageBox(CString((LPCTSTR)this->m_btBuf.GetData()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  函数:BOOL CFTPClient::GetLine()
//
//  描述:
//      得到文件列表中的一行数据
//      
//  
//  参数:
//       -ndx 行号
//
//       -strLine  返回行中的字符
//  返回:
//
//      -BOOL 成功返回 TRUE 否则返回  FALSE
//  
//                                                                           吴庆民  2005.5.4
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::GetLine (int ndx,CString &strLine)
{
	CString temp = CString((LPCTSTR)this->m_btBuf.GetData());
	int i,j,num;
	i=0;num = 1;
	while (num<=ndx )
	{
		j=i; 
		if((i = temp.Find ("\n",j+2))==-1) return FALSE;
		if (num == 1)
		{
			strLine = temp.Mid (0,i-1);
		}
		else
		{
			strLine = temp.Mid (j,i-j);
		}
		num++;
	}
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  函数:BOOL CFTPClient::MoveFile ()
//
//  描述:
//      上传或下载文件,不支持多线程,可以在这个函数上进行一下扩展
//      
//  
//  参数:
//      -strRemoteFile 远程文件名
//      -strLocalFile  本地文件名
//      -bPasv         是否为被动模式传输
//      -bGet          是否为下载文件
//
//  返回:
//      -BOOL 成功返回 TRUE 否则返回  FALSE
//  
//                                                                           吴庆民  2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::MoveFile (CString strRemoteFile,CString strLocalFile,BOOL bPasv,BOOL bGet)
{
	CFile flDataFile;
	CString strCommand ;
	
	int pos = 0;
	UINT uServSock,uLocalSock;
	CString strHost;
	CSocket sServ;
	CAsyncSocket asListen;
	int i=0,j=0,num,numread,numsent;
	CString strTemp;

	const int BUFSIZE = 4096;
	char cbuf[BUFSIZE];
	if (!flDataFile.Open (strLocalFile,(bGet?CFile::modeCreate|CFile::modeWrite:CFile::modeRead)))
	{
		this->SetMessage ("上传或下载的文件在本地不能打开!");
		return FALSE;
	}

	//准备传输
	strCommand = "TYPE I \n\r";
	if (!this->WriteStr (strCommand)) return FALSE;
	
	if (!this->ReadStr ()) return FALSE;
	this->SetMessage (this->m_strMsg );

	if (bPasv)
	{
		strCommand = "PASV \n\r";
		if (!this->WriteStr (strCommand)) return FALSE;
		if (!this->ReadStr ()) return FALSE;
		this->SetMessage (this->m_strMsg );

		//if ((==-1&&(j=this->m_strMsg.Find ("/)"))==-1) return FALSE;
		i=this->m_strMsg.Find ("(");
		j=this->m_strMsg.Find (")");
		if (i==-1||j==-1) 
		{
			this->SetMessage ("响应错误!");
		}

		strTemp = this->m_strMsg.Mid (i+1,(j-i)-1);
		
		i = strTemp.ReverseFind (',');
		uServSock = atol(strTemp.Right (strTemp.GetLength () - (i+1)));
		
		strTemp = strTemp.Left (i);
		//this->SetMessage (strTemp);
		i = strTemp.ReverseFind (',');

		uServSock += 256*atol(strTemp.Right (strTemp.GetLength () - (i+1)));
		
		strHost = strTemp.Left (i);

		


		while(1)
		{
			if ((i=strHost.Find (','))==-1) break;
			strHost.SetAt (i,'.');
		}
		//this->SetMessage (strHost);

		//CString temp;
		//temp.Format (strHost+"\n%d",uServSock );
		//this->SetMessage (temp);
		
	}
	else
	{
	
		if (!this->m_pSocket->GetSockName (strHost,uLocalSock)) return FALSE;
		while(1)
		{
			if ((i=strHost.Find ("."))==-1) break;
			strHost.SetAt (i,',');
		}
		if (!(sServ.Create ())||!(sServ.Listen ())) return FALSE;
		if(!sServ.GetSockName (strTemp,uLocalSock )) return FALSE;

		strHost.Format (strHost+",%d,%d",uLocalSock/256,uLocalSock%256);

		strCommand = "PORT " + strHost ;
		strCommand += "\n\r";

		if (!(this->WriteStr (strCommand))) return FALSE;
		if (!(this->ReadStr ())) return FALSE;
		this->SetMessage (this->m_strMsg );
	}
	
	
	//发送下载或上传命令
	if (bGet)
	{
		strCommand = "RETR" + strRemoteFile;
		strCommand += "\n\r";
	}
	else
	{
		strCommand = "STOR" + strRemoteFile;
		strCommand += "\n\r";
	}

	
	if (!this->WriteStr (strCommand)) return FALSE;

	if (bPasv)
	{
		if (!(asListen.Create ()) )
			return FALSE;
		asListen.Connect (strHost, uServSock);
	}

	if (!this->ReadStr ()) return FALSE;
	this->SetMessage (this->m_strMsg );
	
	
	if (this->m_fc != "1")
	{
		this->SetMessage ("文件传输不成功!");	
		return FALSE;
	}
	

	if(!bPasv&&!sServ.Accept (asListen)) return FALSE;

	//数据传输
	DWORD lpArgument;
	if (!asListen.AsyncSelect ()||!asListen.IOCtl (FIONBIO,&lpArgument)) return FALSE;
	
	while(1)
	{
		TRY
		{
			if (bGet)
			{
				if (!(num=asListen.Receive (cbuf,BUFSIZE,0))) 
					break;
				else

					flDataFile.Write (cbuf,num);
			}
			else
			{
				if (!(numread = flDataFile.Read (cbuf,BUFSIZE))) 
					break;
				else
					if (!(numsent = asListen.Send (cbuf,numread,0))) break;
				if (numread != numsent)
					flDataFile.Seek (numsent - numread,CFile::current);
				pos += numsent;
				m_pWnd ->SetPos(pos);
			}
		}
		CATCH(CException ,e)
		{
			this->SetMessage ("数据传输过程中被中断!");
			return FALSE;
		}
		END_CATCH
		
	}
	asListen.Close ();
	flDataFile.Close ();

	if (!this->WriteStr ("\n\r")) return FALSE;
	this->ReadStr ();
	this->SetMessage (this->m_strMsg );

	return TRUE;


}


void CFTPClient::SetWnd (CftpclientDlg  *pWnd)
{
	this->m_pWnd = pWnd;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  函数:void CFTPClient::SetMessage ()
//
//
//  描述:
//     用于把信息在窗口上显示,在用这个函数之前,先设置窗口.如果觉得没有必要,可以将函数中的语句注掉。
//     
//  参数:
//       -strMsg 要发送的信息

//  返回:
//      -无
//  
//                                                                           吴庆民  2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
void CFTPClient::SetMessage (CString strMsg)
{
	this->m_pWnd->SetMsg(strMsg);	
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  函数:BOOL CFTPClient::GetFtpFileInfo ()
//
//  描述:
//      将信息进行解析。
//      
//  
//  参数:
//       -strOutPut 发送的命令内容,具本格式参考FTP相关资料

//  返回:
//      -BOOL 成功返回 TRUE 否则返回  FALSE
//  
//                                                                           吴庆民  2005.4.19
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTPClient::GetFtpFileInfo (int ndx,FTP_FILE_INFO &ftpFileInfo)
{
	CString strLine ; //文件的所有信息
	CString strTemp;
	int i;
	if (!this->GetLine (ndx,strLine)) return FALSE;
	i = strLine.Find  (' ',0);
	strTemp = strLine.Left (i);
	ftpFileInfo.strPower = strTemp;//得到权限值
	/*
	if (strTemp.Left(1) == "d") 
		ftpFileInfo.isDir = TRUE;
	else
		ftpFileInfo.isDir = FALSE;
	*/

	strLine = strLine.Right (strLine.GetLength () - (i+3));
	i = strLine.Find (' ',1);
	//strTemp = strLine.Left (i);
	strLine = strLine.Right (strLine.GetLength () - (i+10));
	i= strLine.Find (' ',1);
	strLine = strLine.Right (strLine.GetLength () - (i+8));
	i = strLine.Find (' ',0);
	strTemp = strLine.Left (5);
	char *temp = strTemp.GetBuffer ();
	ftpFileInfo.nSize = atol(temp);
	strLine = strLine.Right (strLine.GetLength () - (i+1));

	i = strLine.ReverseFind (' ');
	strTemp = strLine.Right (strLine.GetLength () - (i));
	strLine = strLine.Left (i);
	ftpFileInfo.strFileName  = strTemp ;
	ftpFileInfo.strDate = strLine;

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -