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

📄 ftpclient.cpp

📁 一个用来模拟FTP工作流程的小程序
💻 CPP
字号:
#include "Comm.h"
#define MAX_SIZ 256

WComm w;
char Path[MAX_SIZ];

bool EnCodeCmd(char *CmdBuffer,char *Cmd);
void Get();
void Put(char *Cmd);
void Dir();
void Cd(char *Cmd);
void Exit();
void Help(char *Cmd);

void main(int argc,char *argv[])
{
	char CurrentPath[MAX_SIZ];
	char CmdBuffer[MAX_SIZ];
	char Cmd[MAX_SIZ];
	char rec_ack[32] = "";
	//参数格式判断
	if(argc!=3)
	{
		printf("usage: %s <ServerIP> <ServerPort>",argv[0]);
		exit(1);
	}

	if(w.connectServer(argv[1],(int)atoi(argv[2]))==0)
	{
		printf("连接服务器失败!\n");
		exit(2);
	}
	printf("服务器连接成功!\n");
	
    w.recvData(CurrentPath,MAX_SIZ);	//接受服务器当前目录信息

	strcpy(Path,CurrentPath);			//设置当前路径	
	while(true)		//循环输入命令
	{
		printf("%s>",Path);			//显示目录信息
		gets(CmdBuffer);

		if(!EnCodeCmd(CmdBuffer,Cmd))	//如果命令格式错误,提示用户重新输入命令
		{
			printf("无效的命令,或命令格式有误!\n");
		}
		else						//命令格式正确
		{
			if(Cmd[0]=='5')			//如果是help命令
			{
				Help(Cmd);						
				continue;
			}
			w.sendData(Cmd);        //发送命令
			w.recvData(rec_ack,32);
			w.sendData("success!");

			if(strcmp(rec_ack,"0")==0)
			{
				printf("已经断开了和服务器的连接,程序将要推出执行!\n");
				break;
			}
			strcpy(rec_ack,"0");

			switch(Cmd[0])
			{
				case '0': Get();
				      break;
				case '1': Put(Cmd);
					  break;
				case '2': Dir();
					  break;
				case '3': Cd(Cmd);
				      break;
				case '4': Exit();
			}
		}
	}
}


bool EnCodeCmd(char *CmdBuffer,char *Cmd)//按照协议约定对用户命令字符串进行编码
{
	char temp[MAX_SIZ];
	bool flag=true;
	int item,i,j,k,n;
	item=0;
	for(i=0;CmdBuffer[i]!='\0';i++)		//提取命令字符串中的命令段
	{
       if(CmdBuffer[i]!=' ')
		   temp[item++]=CmdBuffer[i];
	   else
	   {
		   break;
	   }

	}
	temp[item]='\0';

	strupr(temp);						//把命令段转换成大写
	//解析命令,如果正确,则对命令进行编码,负责返回false
	if(strcmp(temp,"GET")==0)			
	{
		Cmd[0]='0';						//get命令
	}
	else if(strcmp(temp,"PUT")==0)
	{
		Cmd[0]='1';						//put命令
	}
	else if(strcmp(temp,"DIR")==0)
	{
		Cmd[0]='2';						//dir命令
	}
	else if(strcmp(temp,"CD")==0)
	{
		Cmd[0]='3';						//cd命令
	}
	else if(strcmp(temp,"EXIT")==0)
	{
		Cmd[0]='4';						//exit命令
	}
	else if(strcmp(temp,"HELP")==0)
	{
		Cmd[0]='5';						//help命令
	}
	else
	{
		flag=false;
		return flag;
	}
	//解析命令的参数
	Cmd[1]=0;
	item=0;
	n=3;
	for(j=i;CmdBuffer[j]!='\0';j++)
	{
		if(CmdBuffer[j]!=' ')
		   temp[item++]=CmdBuffer[j];
		else
		{
			if(item==0)
				continue;
			else
			{
				temp[item]='\0';
				Cmd[1]=Cmd[1]+1;
				Cmd[n++]=item;

				for(k=0;k<item;k++)
				{
					Cmd[n++]=temp[k];
				}
				item=0;
			}
		}
	}
	if(item!=0)
	{
		temp[item]='\0';
		Cmd[1]=Cmd[1]+1;
		Cmd[n++]=item;

		for(k=0;k<item;k++)
		{
		Cmd[n++]=temp[k];
		}
	}
	Cmd[n]='\0';
	Cmd[2]=n;
	//判断参数的格式是否正确
	if((Cmd[0]=='0' && Cmd[1]<1) || (Cmd[0]=='1' && Cmd[1]<1) || (Cmd[0]=='2' && Cmd[1]>1)
		|| (Cmd[0]=='3' && Cmd[1]!=1) || (Cmd[0]=='5' && Cmd[1]>1))
		return false;
	return flag;
}


void Get()
{
	char filename[1025] = "";
	char filesize[33] = "";
	char fileBuffer[1025] = "";
	char receiveBuffer[1024] = "";
	char sendBuffer[1024] = "";

	// get the arc from the server, to check a valid file name
	w.recvData(receiveBuffer, 1);
	if(receiveBuffer[0] == 1)
	{
		printf("Bad command with an invalid filename.\n");
		return;
	}
	else
	{
		// do nothing
	}

	sendBuffer[0] = 1;
	w.sendData(sendBuffer);
	strcpy(sendBuffer, "0");

	// get the arc from the server to see if it is a valid file
	w.recvData(receiveBuffer, 1024);

	if(receiveBuffer[8] == 2)  // no such a file in the server
	{
		printf("There is no such a file in the server, Please check and try again.\n");
		return;
	}
	else
	{
		printf("Get the file. Please wait.\n");
	}

	sendBuffer[0] = 1;
	w.sendData(sendBuffer);

	// first, get the filename comes from the server
	w.recvData(filename, 1024);
	sendBuffer[0] = 1;  // recv filename OK
	w.sendData(sendBuffer);
	strcpy(sendBuffer, "0");
	
	// second, get the filesize from the server
	w.recvData(filesize, 32);
	long size = atol(filesize);
	if(size > 0)
	{
		sendBuffer[0] = 1;
		w.sendData(sendBuffer);
	}
	else
	{
		sendBuffer[0] = 2;
		w.sendData(sendBuffer);
	}
	strcpy(sendBuffer, "0");

	w.recvData(receiveBuffer, 1);
///////////////////////////////////////////////////////////////////////////////
/*
	// third, create a new file in the client disk
	FILE *fw = NULL;
	fw = fopen(filename, "wb");
	if(fw == NULL)
	{
		printf("can not receive the new file, check your disk please.\n");
		return;
	}
*/
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
	FILE *fw = NULL;
	fw = fopen(filename, "a+b");
	if(fw == NULL)
	{
		printf("can not receive the new file, check your disk please.\n");
		return;	
	}
	
	fseek(fw, 0L, SEEK_END);
	long size_already = ftell(fw);

	strcpy(filesize, "0");
	_ltoa(size_already, filesize, 10);
	
	w.sendData(filesize);
	w.recvData(receiveBuffer, 1024);
	strcpy(filesize, "0");
	strcpy(receiveBuffer, "0");

	sendBuffer[0] = 1;
	w.sendData(sendBuffer);
	strcpy(sendBuffer, "0");
///////////////////////////////////////////////////////////////////////////////
	
	long size_backup = size;
	size = size - size_already;
	int last_number = int(((1.0*size_already)/size_backup)*60);
	printf("===========================Progress=========================\n");  // 60 characters
	for(int i=0; i<last_number; i++)
		printf("-");

	while(size > 0)
	{
		if(size >= 1024)
		{
			w.recvData(fileBuffer, 1024);
			fwrite(fileBuffer, 1024, 1, fw);
			
			sendBuffer[0] = 1;
			w.sendData(sendBuffer);

			strcpy(fileBuffer, "0");
			strcpy(sendBuffer, "0"); 

			int all_number = int((1-(1.0*size)/size_backup)*60);
			for (int i=0; i<all_number-last_number; i++)
				printf("-");
			last_number = all_number;
		}
		else
		{
			w.recvData(fileBuffer, size);
			fwrite(fileBuffer, size, 1, fw);
			
			sendBuffer[0] = 1;
			w.sendData(sendBuffer);

			strcpy(fileBuffer, "0");
			strcpy(sendBuffer, "0");

			for (int i=0; i<60-last_number; i++)
				printf("-");
		}

		size -= 1024;
	}

	printf("\n============================================================\n");  // 60 characters
	fclose(fw);

	printf("receive %s OK\n", filename);
}
void Put(char *Cmd)
{
	int filenum=Cmd[1];
	int i,j,temp_add,temp_length;
	HANDLE h;
	WIN32_FIND_DATA lpFindFileData ;
	char file[MAX_SIZ][MAX_SIZ];
	int file_add[MAX_SIZ];
	file_add[0]=4;
	char rec[32] = "";
    
	for(i=0;i<filenum;i++)//解析出所有的纯文件名
	{
		temp_add=file_add[i];
		temp_length=Cmd[file_add[i]-1];
		for(j=0;j<temp_length;j++)
		{
			file[i][j]=Cmd[temp_add++];
		}	
		file[i][j]='\0';
		file_add[i+1]=temp_add+1;   
	}
    

	for(i=0;i<filenum;i++) //判断用户输入的文件是否存在
	{		
	    h=FindFirstFile(file[i],&lpFindFileData);
		if(h==INVALID_HANDLE_VALUE)
		{
			printf("the file named '%s' is not available,please check it!\n",file[i]);
            w.sendData("0");//如果有一个不存在,向服务器发送一个停止发送的标识,并退出
			return;
		}	    
	}
	FindClose(h); 
	
	w.sendData("1");//如果用户输入的文件都存在,向服务器发送一个发送文件的请求
	w.recvData(rec,32);//接受服务器的反馈信息
   
  
	for(i=0;i<filenum;i++)//循环发送文件
	{
		w.fileSend(file[i]);
		printf("The file has been sended successfully...\n");
	}
}
//dir命令
void Dir()
{
	char	recinf[MAX_SIZ];	//接受命令缓冲区
	char    recdata[1024];		//接受数据缓冲区
	char    temp[256];
	int i,m,n,s,k;					//其中m用来计数文件夹个数,n用来计数文件个数,s用来表示当前文件名的长度
	w.recvData(recinf,MAX_SIZ);
	w.sendData("success");

	//判断服务器返回的信息
	if(strcmp(recinf,"0")==0)
	{
		printf("参数文件不存在,请检查参数是否输入正确\n");
		return;
	}
	if(strcmp(recinf,"2")==0)
	{
		printf("参数文件存在,但不是目录,请检查参数是否输入正确\n");
		return;
	}
	if(strcmp(recinf,"3")==0)
	{
		printf("对不起,你无权查看该目录下的文件信息\n");
		return;
	}
	m=0,n=0;

	w.recvData(recdata,1024);//接受目录信息数据
	w.sendData("1");

	printf("	%s 的目录\n",Path);
	while(1)//打印目录信息
	{
		i=1;
		while(recdata[i]!='\0')
		{
			s=recdata[i++];
			if(recdata[i++]=='f')
			{
				printf("	");
				n++;				
			}
			else
			{
				printf("<DIR>	");
				m++;
			}
			for(k=0;k<s;k++)
				temp[k]=recdata[i++];
			temp[k]='\0';
			printf("%s\n",temp);
		}
		if(recdata[0]=='0')
			break;
			w.recvData(recdata,1024);//如果目录信息没有全部接受过来,则继续接收!
			w.sendData("1");
	}
	printf("	%d个文件\n",n);
	printf("	%d个文件夹\n",m);
}


void Cd(char *Cmd)
{
    char temp[MAX_SIZ];
    char C_path[MAX_SIZ];//改变后的路径
    int P_len=0;
    int p_num,i=0;//参数个数
    p_num=Cmd[1];
    P_len=Cmd[3];//参数长度
    
    if(Cmd[4]=='.'&&Cmd[5]!='.')//CD.的情况Cmd[4]=='.'&&Cmd[3]==1
	{ 
      if(Cmd[5]!='\0')
		{
		   printf("参数格式不正确,重新输入!\n");		   
		}
	  return;		
	}
    else if( Cmd[4]=='.'&&Cmd[5]=='.')//cd..的情况 Cmd[3]==2&&Cmd[4]=='.'&&Cmd[5]=='.'
	{
       if(Cmd[6]=='\0')
	   {
	      while(Path[i]!='\0')
		  {
		      C_path[i]=Path[i];
		      i++;
		  }
	      C_path[i]='\0';
	      int j=i;
		  while(C_path[j]!='\\'&&j>0)
		  {		  
             j--;
		  }

		  if(j!=0)
		  {
			  C_path[j]='\0'; 
              strcpy(Path,C_path);			  
		  }
	   }
	   else
	   {
		   printf("参数格式不正确,请重新输入!\n");
	   }
   	}
	else//cd 后跟一个文件夹名字
	{
		w.recvData(C_path,MAX_SIZ);
		if(C_path[0]=='1')          //该文件夹存在
		{
			for(int k=0;k<P_len;k++)
			{
				temp[k]=Cmd[k+4];
			}
			temp[k]='\0';
	   strcat(Path,"\\");
	   strcat(Path,temp);	
	}
	else 
	{
	    printf("系统找不到指定路径!");
		cout<<endl;
	}
  }

}

void Exit()
{
	exit(1);
}
void Help(char *Cmd)
{
	char temp[32];
	if(Cmd[1]==0)
	{
		printf("GET 命令用于从FTP服务器下载一个或者多个文件!\n");
		printf("PUT 命令用于向FTP服务器上传一个或者多个文件!\n");
		printf("DIR 命令显示FTP服务器上的文件列表!\n");
		printf("CD 命令用于进入FTP服务器上的一个指定目录!\n");
		printf("EXIT 命令用于退出FTP服务器!\n");
		printf("HELP 命令用于显示该系统的帮助信息!\n");
		return;
	}
	for(int i=0;i<Cmd[3];i++)
	{
		temp[i]=Cmd[i+4];
	}
	temp[i]='\0';
	strupr(temp);

	if(strcmp(temp,"GET")==0)
	{
		printf("GET	filename1 [filename2]...\n	GET 命令用于从FTP服务器下载一个或者多个文件!\n");
	}
	else if(strcmp(temp,"PUT")==0)
	{
		printf("PUT	filename1 [filename2]...\n	PUT 命令用于向FTP服务器上传一个或者多个文件!\n");
	}
	else if(strcmp(temp,"DIR")==0)
	{
		printf("DIR	[Dir1]...\n	DIR 命令显示FTP服务器上的文件列表!\n");
	}
	else if(strcmp(temp,"CD")==0)
	{
		printf("CD	Dir\n	CD 命令用于进入FTP服务器上的一个指定目录!\n");
	}
	else if(strcmp(temp,"EXIT")==0)
	{
		printf("EXIT	\n	EXIT 命令用于退出FTP服务器!\n");
	}
	else if(strcmp(temp,"HELP")==0)
	{
		printf("HELP	[command]\n	HELP 命令用于显示该系统的帮助信息!\n");
	}
	else
	{
		printf("帮助程序不支持这个命令!\n");
	}
}

⌨️ 快捷键说明

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