linux 下简单的ftp客户端程序

该ftp的客服端是在linux下面写,涉及的东西也比较简单,如前ftp的简单介绍,知道ftp主要的工作流程架构,套接字的创建,还有就是字符串和字符的处理。使用的函数都是比较简单平常易见的,写的时候感觉有将以前学的函数从新巩固一遍。这个简易的ftp客服端只是完成了基本的工作,还有许多的问题有待解决。如:目前最大的问题是使用pasv(被动模式)连接的时候,某些情况下会出现运行错误或同一个运行程序中使用两次pasv的被动连接就是出现运行错误而退出。注意:ftp的测试最好是用linux平台下搭建,连接编码不同ftp会出现错误。

转载请标明出处
代码如下:
/*************************
方便测试ftp:172.16.120.77
author:fengbo
*************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<unistd.h>
#include<netdb.h>
#include<curses.h>
#defineMAXSIZE1024
#definebuff512
 
   
char*data_port;
intport;
char*p,*ptr;
 
   
intc_sockfd,d_sockfd;
intread_status,write_status;
//
charread_buf[200];//控制端口缓存
charread_d_buf[512];//数据端口缓存
charsend_buf[100];
charcommand[40];
charcom_input[15];//输入字符缓存
charpara_input[20];
 
   
structsockaddr_inserveraddr_d;
///
staticvoiddisplay_order();//命令提示
staticvoidftp_d_port();//pasv获得端口
staticvoidftp_c_socket(intargc1,char**argv1);//命令端口创建
staticvoidftp_d_socket(char*argv2);//数据端口创建
staticvoidset_pasv(char*argv3);//设置被动模式
///
staticvoidftp_c_socket(intargc1,char**argv1){
 
   
intret,i,com_len=0;
intcom_i=0,para_i=0;
into_file,r_file,w_file;//文件的描述符
char*com_status,*para_status;
structsockaddr_inserveraddr_c;//网络字节序序存的结构体变量
socklen_tsock_size;
 
   
chardir_name[15];//dir的当前目录
charfile_name[20];
charusername[20];
charpassword[20];
charcatalog[20];//需要cd的目录
chardownload_file[20];
charmkdir_catalog[20];//创建目录
 
   
/
sock_size=sizeof(structsockaddr);
serveraddr_c.sin_family=AF_INET;
serveraddr_c.sin_port=htons(21);
serveraddr_c.sin_addr.s_addr=inet_addr(argv1[1]);
memset(&(serveraddr_c.sin_zero),0,8);
c_sockfd=socket(AF_INET,SOCK_STREAM,0);//创建sock套接字
if(c_sockfd<0){
 
   
perror("creatsocketerror!\n");
return;
}
 
   
ret=connect(c_sockfd,(structsockaddr*)&serveraddr_c,sock_size);
if(ret<0){
 
   
perror("connecterror!\n");
return;
}
printf("connecttheserverFTPsuccessfully!\n");
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp的链接欢迎信息
if(read_status==-1){
perror("errortogaintheftpwelconmeinformation!\n");
}
printf("theinformation:%s\n",read_buf);
/login//
printf("--------------------------pleasetologin--------------------------\n");
printf("\n");
printf("***username:");
scanf("%s",username);
getchar();
printf("\n");
printf("***password:");
scanf("%s",password);
 
   
getchar();
printf("\n");
printf("--------------------------------------------------------------------\n");
 
   
///username//
memset(read_buf,0,sizeof(read_buf));
sprintf(send_buf,"USER%s\r\n",username);
 
   
write_status=write(c_sockfd,send_buf,strlen(send_buf));
if(write_status==-1){
perror("failuretosendtheusername\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
if(atoi(read_buf)!=331){
printf("errortologintheftp'username'\n");
}
printf("theinformation:%s\n",read_buf);
 
   
/password//
memset(send_buf,0,sizeof(send_buf));
memset(read_buf,0,sizeof(read_buf));
sprintf(send_buf,"PASS%s\r\n",password);
 
   
write_status=write(c_sockfd,send_buf,strlen(send_buf));
if(write_status==-1){
perror("failuretosendthepassword\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
if(atoi(read_buf)!=230){
printf("errortologintheftp'password'\n");
exit(-1);
}
printf("theinformation:%s\n",read_buf);
 
   
///设置PASV模式/
//set_pasv();
///获取端口函数/
//ftp_d_port();
发送数据端口请求/
//ftp_d_socket(argv1[1]);
//displaythecommand
display_order();
///命令控制//
 
   
while(1){
printf("%sftp>",username);
scanf("%s",command);//从键盘获取命令和参数
getchar();
com_len=strlen(command);//长度
if(com_len>5){
com_status=strstr(command,"-");//取命令和参数分界点
while(command[com_i]!=*com_status){
com_input[com_i]=command[com_i];
com_i++;
}//获取到命令
//printf("%s\n",com_input);
com_status++;
for(para_i=0;para_i<=(com_len-com_i-1);para_i++){
para_input[para_i]=*com_status;
com_status++;
}//获取到参数
//printf("%s\n",para_input);
com_i=0;
}
else{
strcpy(com_input,command);
}
//大小写转换///
/*for(i=0;i<strlen(command);i++){
 
   
if(strcmp("command[i]","a")>=0){
command[i]=(command[i]-32);
}
 
   
}*/
set_pasv(argv1[1]);
if(strcmp(com_input,"PWD")==0){
///当前路径/
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
 
   
sprintf(send_buf,"PWD\r\n");
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'PWD'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
}
elseif(strcmp(com_input,"DIR")==0){
///显示目录文件///
 
   
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
strcpy(dir_name,para_input);
 
   
sprintf(send_buf,"LIST%s\r\n",dir_name);
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'LIST'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
printf("%s\n",read_buf);
//if(atoi(read_buf)!=){
 
   
//printf("errortosetthePASVmodel\n");
//}
memset(read_d_buf,0,sizeof(read_d_buf));
while(read(d_sockfd,read_d_buf,sizeof(read_d_buf))>0){
 
   
printf("%s",read_d_buf);
memset(read_d_buf,0,sizeof(read_d_buf));
}
close(d_sockfd);
memset(&serveraddr_d,0,sizeof(serveraddr_d));
}
elseif(strcmp(com_input,"QUIT")==0){
/退出/
close(d_sockfd);
printf("数据端口已关闭\n");
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
 
   
sprintf(send_buf,"QUIT\r\n");
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'RETR'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
break;
}
elseif(strcmp(com_input,"GET")==0){
 
   
/下载文件/
 
   
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
memset(read_d_buf,0,sizeof(read_d_buf));
 
   
strcpy(download_file,para_input);
sprintf(send_buf,"RETR%s\r\n",download_file);
write_status=write(c_sockfd,send_buf,strlen(send_buf));
if(write_status==-1){
perror("failuretosendtheinformationfor'RETR'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
 
   
o_file=open(download_file,O_WRONLY|O_CREAT|O_TRUNC,0644);//创建文件客服端
if(o_file==-1){
printf("errortoopenthe%s\n",file_name);
exit(-1);
}
 
   
while((r_file=read(d_sockfd,read_d_buf,sizeof(read_d_buf)))>0){
 
   
write(o_file,read_d_buf,r_file);//写入文件
memset(read_d_buf,0,sizeof(read_d_buf));
}
printf("transportthefilesuccessfuly!\n");
close(o_file);
close(d_sockfd);
memset(&serveraddr_d,0,sizeof(serveraddr_d));
}
elseif(strcmp(com_input,"CD")==0){
///跳转目录/
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
 
   
strcpy(catalog,para_input);
sprintf(send_buf,"CWD%s\r\n",catalog);
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'DELE'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
}
elseif(strcmp(com_input,"DEL")==0){
///删除文件/
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
 
   
strcpy(file_name,para_input);
sprintf(send_buf,"DELE%s\r\n",file_name);
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'DELE'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
}
elseif(strcmp(com_input,"MKDIR")==0){
///创建目录/
memset(read_buf,0,sizeof(read_buf));
memset(send_buf,0,sizeof(send_buf));
 
   
strcpy(mkdir_catalog,para_input);
sprintf(send_buf,"MKD%s\r\n",mkdir_catalog);
write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
if(write_status==-1){
perror("failuretosendtheinformationfor'DELE'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
//if(atoi(read_buf)!=257){
//printf("errortosetthePASVmodel\n");
//}
printf("%s\n",read_buf);
}
else{
printf("***************thecommanderror!****************\n");
display_order();//显示命令
}
}
 
   
 
   
}
//PASV被动模式设置/
staticvoidset_pasv(char*argv3){
memset(send_buf,0,sizeof(send_buf));
memset(read_buf,0,sizeof(read_buf));
sprintf(send_buf,"PASV\r\n");
write_status=write(c_sockfd,send_buf,strlen(send_buf));
if(write_status==-1){
perror("failuretosendtheinformationfor'PASV'\n");
}
read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
if(read_status==-1){
perror("errortogaintheftpinformation!\n");
}
printf("%s",read_buf);
if(atoi(read_buf)!=227){
printf("errortosetthePASVmodel\n");
}
ftp_d_port();//获取端口
ftp_d_socket(argv3);//数据套接字创建
 
   
}
/获取端口函数实现///
staticvoidftp_d_port(){
 
   
char*port_status1,*port_status2,*index,extend,extend_1;
intport_temp1[4],port_temp2[4];//当时出现错误,变量为int型
intport_i=0,port_ii=0,count,count_i,count_ii;
inttemp=0,temp1=0,temp2,port_point;
 
   
port_status1=strstr(read_buf,"(");//取“(”里面的
port_status1++;
for(port_point=0;port_point<4;port_point++){//取第4个逗号位置
port_status2=strstr(port_status1,",");
port_status2++;
port_status1=port_status2;
}
port_status2=strstr(port_status1,",");//取第5个逗号位置
while(port_status1!=port_status2){
extend=*port_status1;
port_temp1[port_i]=(int)(extend-48);//获取5~6逗号间数据
port_i++;
port_status1++;
}
port_status2++;
port_status1=port_status2;
port_status2=strstr(port_status1,")");//取")"的位置
while(port_status1!=port_status2){
extend_1=*port_status1;
port_temp2[port_ii]=(extend_1-48);//获得")"之前的数据
port_ii++;
port_status1++;
}
count_i=port_i;
for(count=0;count<port_i;count++){
if(count_i==3){
count_ii=100;
}
elseif(count_i==2){
count_ii=10;
}
elseif(count_i==1){
count_ii=1;
}
temp=temp+port_temp1[count]*count_ii;//计算p1
count_i--;
}
count_i=port_ii;
for(count=0;count<port_ii;count++){
if(count_i==3){
count_ii=100;
}
elseif(count_i==2){
count_ii=10;
}
elseif(count_i==1){
count_ii=1;
}
temp1=temp1+port_temp2[count]*count_ii;//计算p2
count_i--;
}
port=temp*256+temp1;//p1*256+p2
printf("theinformation:%s\n",read_buf);
}
//命令提示
staticvoiddisplay_order(){
printf("****************************************************\n");
printf("youcaninputtheCommand:\n");
printf("DIR,PWD,GET,PUT,QUIT,CD,DEL,MKDIR\n");
printf("attention:命令和参数间用'-'分开\n");
printf("****************************************************\n");
 
   
}
///数据传送端口
 
   
staticvoidftp_d_socket(char*argv2){
 
   
intret_d;
//structsockaddr_inserveraddr_d;
socklen_tsock_d_size;
 
   
sock_d_size=sizeof(structsockaddr);
serveraddr_d.sin_family=AF_INET;
serveraddr_d.sin_port=htons(port);
serveraddr_d.sin_addr.s_addr=inet_addr(argv2);
memset(&(serveraddr_d.sin_zero),0,8);
d_sockfd=socket(AF_INET,SOCK_STREAM,0);
if(d_sockfd<0){
perror("creatdata_socketerror\n");
exit(-1);
}
ret_d=connect(d_sockfd,(structsockaddr*)&serveraddr_d,sock_d_size);
if(ret_d<0){
perror("data_connecterror!\n");
exit(-1);
}
printf("connecttheFTPdataportsuccessfully!\n");
}
 
   
intmain(intargc,char**argv){
 
   
ftp_c_socket(argc,argv);
return0;
}
http://xfb2020.blog.163.com/blog/static/198496112201317113750789/

转载于:https://www.cnblogs.com/pengkunfan/p/3588699.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值