• 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!
    ");
    return;
    }
    
    
    ret=connect(c_sockfd,(structsockaddr*)&serveraddr_c,sock_size);
    if(ret<0){
    
    
    perror("connecterror!
    ");
    return;
    }
    printf("connecttheserverFTPsuccessfully!
    ");
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp的链接欢迎信息
    if(read_status==-1){
    perror("errortogaintheftpwelconmeinformation!
    ");
    }
    printf("theinformation:%s
    ",read_buf);
    /////////////////login//////////////////////////
    printf("--------------------------pleasetologin--------------------------
    ");
    printf("
    ");
    printf("***username:");
    scanf("%s",username);
    getchar();
    printf("
    ");
    printf("***password:");
    scanf("%s",password);
    
    
    getchar();
    printf("
    ");
    printf("--------------------------------------------------------------------
    ");
    
    
    ///////////////username//////////////////////////
    memset(read_buf,0,sizeof(read_buf));
    sprintf(send_buf,"USER%s
    ",username);
    
    
    write_status=write(c_sockfd,send_buf,strlen(send_buf));
    if(write_status==-1){
    perror("failuretosendtheusername
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    if(atoi(read_buf)!=331){
    printf("errortologintheftp'username'
    ");
    }
    printf("theinformation:%s
    ",read_buf);
    
    
    /////////////////password//////////////////////////
    memset(send_buf,0,sizeof(send_buf));
    memset(read_buf,0,sizeof(read_buf));
    sprintf(send_buf,"PASS%s
    ",password);
    
    
    write_status=write(c_sockfd,send_buf,strlen(send_buf));
    if(write_status==-1){
    perror("failuretosendthepassword
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    if(atoi(read_buf)!=230){
    printf("errortologintheftp'password'
    ");
    exit(-1);
    }
    printf("theinformation:%s
    ",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
    ",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
    ",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
    ");
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'PWD'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",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
    ",dir_name);
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'LIST'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    printf("%s
    ",read_buf);
    //if(atoi(read_buf)!=){
    
    
    //printf("errortosetthePASVmodel
    ");
    //}
    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("数据端口已关闭
    ");
    memset(read_buf,0,sizeof(read_buf));
    memset(send_buf,0,sizeof(send_buf));
    
    
    sprintf(send_buf,"QUIT
    ");
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'RETR'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",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
    ",download_file);
    write_status=write(c_sockfd,send_buf,strlen(send_buf));
    if(write_status==-1){
    perror("failuretosendtheinformationfor'RETR'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",read_buf);
    
    
    o_file=open(download_file,O_WRONLY|O_CREAT|O_TRUNC,0644);//创建文件客服端
    if(o_file==-1){
    printf("errortoopenthe%s
    ",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!
    ");
    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
    ",catalog);
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'DELE'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",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
    ",file_name);
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'DELE'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",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
    ",mkdir_catalog);
    write_status=write(c_sockfd,send_buf,strlen(send_buf));//命令写入控制套接连接
    if(write_status==-1){
    perror("failuretosendtheinformationfor'DELE'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    //if(atoi(read_buf)!=257){
    //printf("errortosetthePASVmodel
    ");
    //}
    printf("%s
    ",read_buf);
    }
    else{
    printf("***************thecommanderror!****************
    ");
    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
    ");
    write_status=write(c_sockfd,send_buf,strlen(send_buf));
    if(write_status==-1){
    perror("failuretosendtheinformationfor'PASV'
    ");
    }
    read_status=read(c_sockfd,read_buf,sizeof(read_buf));//读取ftp用户链接的返回信息
    if(read_status==-1){
    perror("errortogaintheftpinformation!
    ");
    }
    printf("%s",read_buf);
    if(atoi(read_buf)!=227){
    printf("errortosetthePASVmodel
    ");
    }
    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
    ",read_buf);
    }
    //////////////////////////命令提示////////////////////////////////////////
    staticvoiddisplay_order(){
    printf("****************************************************
    ");
    printf("youcaninputtheCommand:
    ");
    printf("DIR,PWD,GET,PUT,QUIT,CD,DEL,MKDIR
    ");
    printf("attention:命令和参数间用'-'分开
    ");
    printf("****************************************************
    ");
    
    
    }
    ///////////////////////////数据传送端口////////////////////////////////////
    
    
    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
    ");
    exit(-1);
    }
    ret_d=connect(d_sockfd,(structsockaddr*)&serveraddr_d,sock_d_size);
    if(ret_d<0){
    perror("data_connecterror!
    ");
    exit(-1);
    }
    printf("connecttheFTPdataportsuccessfully!
    ");
    }
    
    
    intmain(intargc,char**argv){
    
    
    ftp_c_socket(argc,argv);
    return0;
    }
    http://xfb2020.blog.163.com/blog/static/198496112201317113750789/
  • 相关阅读:
    批量刷新远程物化视图的方法(备用)
    Oracle 11g中CTE应用示例
    PL/SQL DEVELOPER中查询结果复制出来中文乱码的解决方案
    RHEL5.5 64位下安装Oracle 11g 64位安装前置条件的两种方法
    不良言论屏蔽方案探讨——自说自话方案
    AWWWB 网站克隆器 v2.0发布
    OneNote中到底能放多少种东西?
    Visual Studio 2010 旗舰版 安装问题小记
    WPF命中测试示例(一)——坐标点命中测试
    网页内嵌Windows Media Player播放器的多文件播放方法
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/3588699.html
Copyright © 2020-2023  润新知