使用SOCKET实现FTP的简易客户端

2015-01-17 20:00:57|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:C/C++, 网络通信|来源:唯设编程网

22.  下载FTP服务器指定文件到本地

//下载FTP服务器的指定文件
int CFTP::ftp_download( const char* localfile,const char* remotefile,size_t buf_size /*= 1024*/ )
{ 
	ftp_setpasv();

	sprintf_s(m_cmd,"RETR %s
",remotefile);
	int err = ftp_sendcmd(m_cmd,m_resp,sizeof(m_resp)); 
	if(err)
		return -1;
	//得到返回码
	int code = get_state_code(m_resp);
	//125 Data connection already open; Transfer starting.
	//150 Open BINARY mode data connection for test.step
	if(code != 125 && code != 150)
		return -1;
	//检测本地目录是否存在,不存在则创建目录
	std::string localPath(localfile);
	int iRet = access(localPath.substr(0,localPath.rfind("")).c_str(),0);
	if(iRet){
		local_create_dir(localPath.substr(0,localPath.rfind("")).c_str());
	}
	//本地文件
	FILE* pf = NULL;
	//二进制方式打开
	errno_t s_code = fopen_s(&pf,localfile,"wb"); 
	if(NULL==pf)
		return -1; 

	char* recvbuf = new char[buf_size]; 
	memset(recvbuf,0,buf_size);
	int len = 0; 
	while((len = recv(m_sockdata,recvbuf,buf_size,0))>0) 
	{ 
		err = fwrite(recvbuf,len,1,pf); 
		if(err<0)
			return -1;
	} 
	//删除缓存空间
	delete []recvbuf;
	closesocket(m_sockdata); 
	fclose(pf); 
	//226 Transfer complete.
	err = recv_buf(m_resp,sizeof(m_resp)); 
	if(err || get_state_code(m_resp) != 226)
		return -1;
	return 0; 
} 

与上传一样,建议使用二进制方式打开本地文件进行写入。

23.  获取FTP服务器文件的大小

//获取FTP文件大小
size_t CFTP::ftp_getFileSize( const char* remoteFileName )
{	
	sprintf_s(m_cmd,"SIZE %s
",remoteFileName);
	int err = ftp_sendcmd(m_cmd,m_resp,sizeof(m_resp)); 
	if(err)
		return 0;	

	size_t fileSize = 0;	//文件大小
	int code = -1;			//返回码
	//分离出字符串
	std::string s(m_resp);	
	std::istringstream ss(s);  //拷贝构造输出串流	
	ss>>code>>fileSize;  
	//213 103708394
	if(code == 213)
		return fileSize;
	return 0; 
}

获取FTP服务器文件大小使用SIZE命令。

到此,FTP客户端工具的所有实现函数就介绍完成了,该代码还有很多需要改进的地方,比如接收服务器返回数据使用recv,如果服务器没有发送数据则需要等待超时,这在上传、下载目录的时候延时影响特别明显。如何实现服务器没有发送数据直接返回呢?所以,不完善的地方还希望其它同仁给予指点,转载请注明出处:使用SOCKET实现FTP的简易客户端

发表评论0条 】
网友评论(共?条评论)..
使用SOCKET实现FTP的简易客户端