📄 ftpclient.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 + -