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

📄 tftpclient.cpp

📁 FTPClient的实现文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	char buf[10240];
	switch(cmd){
	// 改名
	case RENAME:{
		snprintf(buf, sizeof(buf), (char*)"RNFR %s\r\n", cmdvalue );//rename from
		int len=strlen(buf);
		int ret = Write(m_hControlChannel,buf,&len);
		if( ret < 0 || len != strlen(buf) ){
			return -1;
		}
		ret = WaitResult(m_hControlChannel);
		if(ret != 350){
			return -1;
		}
		snprintf(buf, sizeof(buf), (char*)"RNTO %s\r\n", returnvalue );//rename to
		if( FTPCommand(buf) != 0 )
			return -1;
		return 0;
	}
	// 获取远端文件状态
	case STATCMD:{
		snprintf(buf, sizeof(buf), (char*)"STAT %s\r\n", cmdvalue);
		int len = strlen(buf);
		int ret = Write(m_hControlChannel,buf,&len);
		if( ret < 0 || len != strlen(buf)){
			return -1;
		}
		ret= WaitResult(m_hControlChannel);
		if(ret !=  213){
			return -1;
		}
		else {
			m_strReplyBuffer[strlen(m_strReplyBuffer) - 1 ] = 0;
			char* p = strchr(m_strReplyBuffer, '\n');
			if( p == NULL )
				return -1;
			p++;
			char* q = strrchr(m_strReplyBuffer, '\n');
			if(q == NULL )
				return -1;
			*(q+1) = 0;
			if( retmaxsize == 0 )
				strcpy(returnvalue, p);
			else
				strncpy(returnvalue, p, retmaxsize);
			return 0;
		}
	}
	/* 改变服务器端当前路径 */
	case CHDIR:
		snprintf(buf,sizeof(buf),(char*)"CWD %s\r\n", cmdvalue);
		return FTPCommand(buf);
	// 获取远端文件的大小
	case SIZE:{
		snprintf(buf, sizeof(buf), (char*)"SIZE %s\r\n", cmdvalue);
		int len=strlen(buf);
		int ret = Write(m_hControlChannel,buf,&len);
		if( ret<0||len!=strlen(buf)){
			return -1;
		}
		ret= WaitResult(m_hControlChannel);
		if(ret/100 !=  2){
			if( ret <= 0 )
				return -1;
			return FTP_E_FILE;
		}
		else {
			char* p = strchr(m_strReplyBuffer, ' ');
			if( p == NULL ) return -1;
			while( *p > '9' || *p < '0') p++;
			if( retmaxsize == 0 )
				strcpy(returnvalue, p );		
			else
				strncpy(returnvalue, p, retmaxsize);	
			return 0;
		}
	}
	/* 改变服务器端路径为当前路径的父目录 */
	case CDUP:
		return FTPCommand("CDUP\r\n");
	/* 删除服务器端指定文件 */
	case DEL:
		snprintf(buf,sizeof(buf),(char*)"DELE %s\r\n", cmdvalue);
		return FTPCommand(buf);
	/* 列出服务器端指定目录(默认为当前目录)的内容,并放入指定的文件中 */
	case LS:
	{
		if(CreateListenSocket()) return -1;
		if(cmdvalue==NULL)
		{
			strcpy(buf,"LIST\r\n");
		}
		else
		{
			snprintf(buf,sizeof(buf),(char*)"LIST %s\r\n", cmdvalue);
		}

		#ifdef _NLIST_
				strcpy(buf,"NLST\r\n");
		#endif
		
		int len = strlen(buf);
		int ret = Write(m_hControlChannel,buf,&len);
		if(ret<0 || len != strlen(buf) ){
			close(m_hListenSocket);
			return -1;
		}

		ret=WaitResult(m_hControlChannel);
		if(ret != 150){
			close(m_hDataSocket);
			close(m_hListenSocket);
			return -1;
		}
		
		ret = Accept(m_hListenSocket,NULL,NULL);
		close(m_hListenSocket);
		if(ret > 0 ){
			m_hDataSocket = ret;
		}
		else {		
			ret = WaitResult(m_hControlChannel);
			if(ret > 500){
				return -2;
			}
			return -1;
		}
	
		int fd;
		if((fd = open(returnvalue, O_CREAT|O_TRUNC|O_RDWR, 0660))<0){
			close(m_hDataSocket);
			perror("open file");
			return -1;
		}
	
		int timer=time(0);
		int totallen=0;
		int tmptime;
		while(1){
			tmptime=time(0);
			if( tmptime >= timer + m_iMaxWaitTime ){
				close(m_hDataSocket);
				printf("time out %d seconds when get a remote file\n", m_iMaxWaitTime);
				close(fd);
				return -1;
			}
			len = 10240;
			ret = Read(m_hDataSocket,buf,&len);
			if( ret != 0 )
				break;
			else if( len == 0 )
				continue;
			timer=tmptime;
			if(write(fd, buf, len) < len) {
				perror("write file");
				close(fd);
				close(m_hDataSocket);
				return -1;
			}
			totallen += len;
		}
	
		close(fd);	
		close(m_hDataSocket);

		ret = WaitResult(m_hControlChannel);
		if( ret == 226 ) return 0 ;
		return -1;		
	}
	/* 显示服务器端当前目录的绝对路径 */
	case PWD:
		if(FTPCommand("PWD\r\n"))return -1;
		{
			char* p1=strchr(m_strReplyBuffer,'\"');
			*strchr(++p1,'\"')=0;
			if( retmaxsize == 0 )
				strcpy(returnvalue,p1);
			else
				strncpy(returnvalue, p1, retmaxsize);
		}
		return 0;
	/* 在服务器端创建目录 */
	case MKDIR:
		snprintf(buf,sizeof(buf),(char*)"MKD %s\r\n", cmdvalue);
		return FTPCommand(buf);
	/* 在服务器端删除目录  */
	case RMDIR:
		snprintf(buf,sizeof(buf),(char*)"RMD %s\r\n", cmdvalue);
		return FTPCommand(buf);
	/* 获得服务器端系统类型 */
	case SYSTYPE:
		if(FTPCommand("SYST\r\n"))return -1;
		*strstr(m_strReplyBuffer,"\r\n")=0;
		if( retmaxsize == 0 )
			strcpy(returnvalue,m_strReplyBuffer+4);
		else
			strncpy(returnvalue,m_strReplyBuffer+4, retmaxsize);
		return 0;
	default:
		printf("valid command\n");
		return -1;
	}				
}

/********************************************************
* function:FTPCommand
* purpose:发送FTP 命令到FTP Server
* return:   FTP_SUCCEED 成功 ,        FTP_FAIL 失败
*
*********************************************************/
int TFTPClient::FTPCommand(const char* strCommand)
{
	int len = strlen(strCommand);
	int ret = Write(m_hControlChannel,(char*)strCommand,&len);
	if( ret < 0 || len!=strlen(strCommand)){
		return -1;
	}
	ret= WaitResult(m_hControlChannel);
	if(ret/100 !=2){
		return -1;
	}
	return 0;	
}
/********************************************************
* function:FTPLogout
* purpose:退出登陆
* return:  
*
*********************************************************/
void TFTPClient::FTPLogout()
{
	FTPCommand("QUIT\r\n");
	close(m_hControlChannel); 


}

/*******************************************************
 *
 *      描述:主机字节序测试
 *      返回:1-高端字节序,0-低端字节序
 *
 ********************************************************/
int TFTPClient::IsBigOrder(){
        union{
                short s;
                char c[sizeof(short)];
        }un;
        
        un.s = 0x0102;
        /*printf("%s:",CPU_VENDOR_OS);*/
        if(sizeof(short) >= 2)    {
                if( un.c[0] == 1 && un.c[1] == 2) {
                        //printf("big-endian\n");
                        return 1;
                }
                else if(un.c[0] == 2&& un.c[1] == 1) {
                        //printf("little-endian\n");
                        return 0;
                }
                else {
                        //printf("unknown\n");
                        return -1;
                }
        }
        else {
                printf("sizeof(short) = %d\n",sizeof(short));
                return -1;
        }
}

/* return: -1:写失败, 0 写成功 */
int TFTPClient::Write(int fd, char* buff, int *len)
{
	fd_set writefds;
	fd_set errfds;
	struct timeval tv;
	int ret;
	
	FD_ZERO(&writefds);
	FD_SET(fd,&writefds);
	FD_ZERO(&errfds);
	FD_SET(fd,&errfds);
	tv.tv_sec=m_iTimeOut;
	tv.tv_usec=0;
	if( select(fd+1, NULL, &writefds, &errfds, &tv) ) {

		if(FD_ISSET(fd, &errfds)) {
			*len = 0;
			return -1;
		}
		else if(FD_ISSET(fd, &writefds)) {
			//如果FTP Server异常中断,会造成此处阻塞			
			ret = write(fd, buff, *len);
			*len = 0;
			if( ret > 0 ) {
				*len = ret;
				return 0;
			}
			else {
				return -1;
			}
		}
	}    
	return -1;
}

/*return : -1,失败,0,成功或者超时,1,EOF */
int TFTPClient::Read(int fd, char* buff, int *len)
{
	fd_set readfds;
	fd_set errfds;
	struct timeval tv;
	int ret;
	
	FD_ZERO(&readfds);
	FD_SET(fd,&readfds);
	FD_ZERO(&errfds);
	FD_SET(fd,&errfds);
	tv.tv_sec = m_iTimeOut;
	tv.tv_usec = 0;
	if( select(fd+1, &readfds, NULL, &errfds, &tv) ) {
		if(FD_ISSET(fd, &errfds)) {
			*len = 0;
			return -1;
		}
		if(FD_ISSET(fd, &readfds)) {
			ret=read(fd, buff, *len);
			*len = 0;
			if( ret == 0)
				return  1;
			if( ret < 0)
				return  -1;
			
			*len = ret;
			return 0;			
		} 
	}
	*len = 0;
	return 0;
}

/* 等待连接,返回:0--超时,-1,错误,连接套接字 */
int TFTPClient::Accept(int fd,struct sockaddr* addr,int* len)
{
	fd_set readfds;
	fd_set errfds;
	struct timeval tv;
	
	FD_ZERO(&readfds);
	FD_SET(fd,&readfds);
	FD_ZERO(&errfds);
	FD_SET(fd,&errfds);
	tv.tv_sec=m_iTimeOut;
	tv.tv_usec=0;

	if(select(fd+1, &readfds, NULL, &errfds, &tv)) {
		if(FD_ISSET(fd,&errfds)) {
			return -1;
		}else if(FD_ISSET(fd,&readfds)) {
			#if defined(_AIX) || defined(__linux__)
				return accept(fd, addr, (socklen_t *)len);
			#else
				return accept(fd, addr, len);
			#endif
		} else{
			return 0;
		}
	}
	
	return 0;
}

/* return -1:失败, 0,超时, 其他,返回应答数字*/
int TFTPClient::WaitResult(int fd)
{
	int tmptime;
	int ret;
	memset(m_strReplyBuffer,0,sizeof(m_strReplyBuffer));
	int totallen=0;
	int len=1;
	int timer=time(0);
	while(1) 
  {
		tmptime=time(0);
		if(tmptime >= timer+m_iMaxWaitTime){
			return 0;
		}
		//len=sizeof(m_strReplyBuffer)-totallen;
		int Nlen=1;
		ret = Read(fd, &m_strReplyBuffer[totallen], &Nlen);
#ifdef _DEBUG_
		write(STDOUT_FILENO, &m_strReplyBuffer[totallen],1);
#endif
		if(ret != 0)
			return -1;
		else if( Nlen == 0 )
			continue;
		totallen += Nlen;


		/* 这里返回多行仔细考虑,多行时,第一行第四个字符是减号 */
		if((m_strReplyBuffer[totallen-2] == '\r' && m_strReplyBuffer[totallen-1] == '\n')
				||m_strReplyBuffer[totallen-1] == 0) 
		{
			int retcode = atol(  m_strReplyBuffer );
			if( strlen( m_strReplyBuffer) < 4  || m_strReplyBuffer[3] != '-' )
			{
				//printf("result:%s\n", m_strReplyBuffer);
				return atol(m_strReplyBuffer);
			}
			
			char* p = m_strReplyBuffer;
			char* q;
			while(GetLine(p, &q) == 0 ) 
			{
				if( strlen(q)>3 && *(q+3) == ' ' && atol(q) == retcode )
				{
					//printf("result:%s\n", m_strReplyBuffer);
					return retcode;
				}
				p = q;
			}/*while*/
		}/*if*/
	}/*while(1)*/
}




int TFTPClient::GetLine( char* src, char** nextline)
{
	char* p = src;
	for( ; *p != 0 ; p++ ) {
		if( *p == '\n' && *(p+1) != 0 ) {
			*nextline = p + 1;
			return 0;
		}
	}
	return -1;
}

⌨️ 快捷键说明

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