IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]linux C 实现FTP客户端

    jsh13417发表于 2015-01-10 11:07:20
    love 0

    ****************************************************************************************

    我已参加2014“博客之星的”评选,觉得我的文章对您有帮助的,请投上您宝贵的一票

    ****************************************************************************************

    参考资料:

    1、使用 Socket 通信实现 FTP 客户端程序

    #include
    #includesocket.h>
    #include<stdlib.h>
    #include<string.h>
    #include<strings.h>
    #include<unistd.h>
    #include<netinetin.h>
    #include
    #include
    #includetypes.h>
    #include<sysstat.h>
    #include
    #define SERV_PORT 21
    #define MAXSIZE 1024
    #define SA struct sockaddr
    static int control_sockfd;
    int npsupport;
    int login_yes;
    int f;//f=0时为默认文件结构
    int login();
    void ftp_list(int control_sockfd);
    void zeromery(char *a,int len);
    void ftp_pwd(int control_sockfd);
    void ftp_changdir(char dir[],int control_sockfd);
    void ftp_quit(int control_sockfd);
    void ftp_creat_mkd(char *path,int control_sockfd);
    void ftp_back(int control_sockfd);
    void ftp_stru(int control_sockfd);
    void ftp_rest(int control_sockfd);
    int ftp_download(int control_sockfd);
    char *itoa(int value, char *string, int radix);
    int  main(int argc,char **argv)
    {
        printf("ftp>");
        char command[MAXSIZE];
        char*cmd;
        scanf("%s",command);
        cmd=command;
        while(*(cmd)==' ')
            cmd++;
    
        if(strncmp(cmd,"login",5)==0)
        {
            login();
            if(login_yes==1)
            {
                while(1)
                {
                comm:            
                    sleep(1);
                    printf("ftp>");
                    zeromery(command,1024);
                    scanf("%s",command);
                    cmd=command;
                    while(*(cmd)==' ')
                    cmd++;
                    if(strncmp(cmd,"pasv",4)==0)
                    {
                        ftp_list(control_sockfd);
                    }
                    if(strncmp(cmd,"port",4)==0)
                    {
                        ftp_list(control_sockfd);
                    }
                    if(strncmp(cmd,"list",4)==0)
                    {
                        ftp_pwd(control_sockfd);
                        ftp_list(control_sockfd);
                    }
                    if(strncmp(cmd,"pwd",3)==0)
                    {
                        ftp_pwd(control_sockfd);
                    }
                    if(strncmp(cmd,"mkdir",5)==0)
                    {
                        char path[60];
                        zeromery(path,60);
                        printf("创建的路径名: ");
                        scanf("%s",path);
                        printf("s/n",path);
                        ftp_creat_mkd(path,control_sockfd);
                    }
                    if(strncmp(cmd,"back",4)==0)
                    {
                        ftp_back(control_sockfd);
    
                        ftp_pwd(control_sockfd);
                    }
                    if(strncmp(cmd,"cd",2)==0)
                    {
                        int i;
                        char path[60];
                        zeromery(path,60);
                        printf("要到的路径:");
                        scanf("%s",path);
                        printf("%s/n",path);
                        ftp_changdir(path,control_sockfd);
                    }
                    if(strncmp(cmd,"get",3)==0)
                    {
                        ftp_pwd(control_sockfd);    
                        ftp_download(control_sockfd);
                    }
                    if(strncmp(cmd,"up",3)==0)
                    {
                        ftp_pwd(control_sockfd);
                        ftp_up(control_sockfd);        
                    }
                    if(strncmp(cmd,"quit",4)==0)
                    {
                        printf("bye^_^/n");
                        close(control_sockfd);
                        break;
                    }
                    printf("支持 list,pwd,mkdir,back,cd,up,get/n");    
            }
            
        }
        else if(login_yes==0)
        { 
            int i;//不成功登录下最多还有两次机会,如果不能在两次登录,则,关闭链接。
            printf("Can not login vsftpd");
            for(i=2;i>0;i--)
            {
                printf("你还有 %d 登录机会/n",i);            
                login();
                if(login_yes==1)
                {
                    goto comm;
                }
            }
            if(i==0)
            {
                printf("你不能在登录!/n");
                close(control_sockfd);
            }
                
        }
        else if (strncmp(cmd,"quit",4)==0)
        {
            ftp_quit(control_sockfd);
            close(control_sockfd);
            
        }
        }
        return 0;
    }
    int login()
    {
        //初始化端口信息
        struct sockaddr_in serv_addr;
        char senddate,recvdate;
        char sendline[MAXSIZE],recvline[MAXSIZE];
        struct hostent *host;
    
        //获取hostent中相关参数
        char name[MAXSIZE],password[MAXSIZE];
        printf("please enter the hostname/n");
        printf("ftp-> ");
        scanf("%s",name);
        host=gethostbyname(name);
        if(host==NULL)
        {
            printf("get host by name is error!/n");
            login_yes=0;
        }
        else
        {
            //创建socket
            control_sockfd=socket(AF_INET,SOCK_STREAM,0);
            if(control_sockfd<0)
            {
                printf("socket is error/n");
                login_yes=0;
            }
        
    
            //设置sockaddr_in 结构体中的相关参数
            bzero(&serv;_addr,sizeof(serv_addr));
            serv_addr.sin_family=AF_INET;
            serv_addr.sin_port=htons(SERV_PORT);
            serv_addr.sin_addr.s_addr=INADDR_ANY;
    
            //调用connect函数发起连接
            char addr[MAXSIZE];
            if((connect(control_sockfd,(SA*)&serv;_addr,sizeof(serv_addr)))<0)
            {
                printf("connect is error/n");
                login_yes=0;
            }
            printf("connect to %s/n",inet_ntop(AF_INET,host->h_addr,addr,1024));
            recvdate=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvdate==-1)
            {
                printf("recvdate is connect error/n");
                login_yes=0;
            }
            else if(strncmp(recvline,"220",3)==0)
            {
                printf("connect success,pelase enter username/n");
                login_yes=1;
            }
            else 
            {
                printf("220 connect is error!");
                login_yes=0;    
            }
    
            //ftp用户登录主体部分
            int sendbytes,recvbytes;
            zeromery(name,1024);
            zeromery(password,1024);
            zeromery(recvline,1024);
            zeromery(sendline,1024);
            printf("ftp-> ");
            scanf("%s",name);//可以支持匿名登录vsftpd
            strcat(sendline,"USER ");
            strcat(sendline,name);
            strcat(sendline,"/r/n");
            printf("--->%s/n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes==-1)
            {
                printf("send is wrong/n");
                login_yes=0;
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"331",3)==0)
            {
                printf("331 please specify the password./n");
            }
            else
            {
                printf("recv date is error./n");
                login_yes=0;
            }
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            printf("ftp-> ");
            scanf("%s",password);
            strcat(sendline,"PASS ");
            strcat(sendline,password);
            strcat(sendline,"/r/n");
            printf("--->%s/n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes==-1)
            {
                printf("pass send is error/n");
                login_yes=0;
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"230",3)==0)
            {
                printf("login success!/n");
                login_yes=1;
            }
            else 
            {
                printf("pass recv is error/n");
                login_yes=0;
            }
    
    
            //支持断点续传
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            strcat(sendline,"REST ");
            strcat(sendline,"0");
            strcat(sendline,"/r/n");
            printf("--->%s/n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes==-1)
            {
                printf("rest send is error!/n");
                login_yes=0;
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes==-1)
            {
                printf("rest recv date is error./n");    
                login_yes=0;    
            }
            if(strncmp(recvline,"350 Restart position accepted (0).",34)==0)
            {
                npsupport=1;
                printf("support 断点续传/n");
                login_yes=1;
            }
            else
            {
                npsupport=0;
                printf("not support 断点续传/n");
                login_yes=0;    
            }
        
    
            //获取服务器版本信息
            zeromery(recvline,1024);
            zeromery(sendline,1024);
            strcat(sendline,"SYST");
            strcat(sendline,"/r/n");
            printf("--->%s/n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes==-1)
            {
                printf("syst send is error/n");
                login_yes=0;
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes==-1)
            {
                printf("syst recv is error/n");
                login_yes=0;
            }
            if(strncmp(recvline,"215 UNIX Type: L8",17)==0)
            {
                printf("%s",recvline);
                login_yes=1;
            }
            else 
            {
                printf("syst recv connectin is error/n");
                login_yes=0;
            }    
        }
        
        return login_yes;
    }
    
    //数组初始化
    void zeromery(char *a,int len)
    {
        int i;
        len=sizeof(a);
        for(i=0;i<0)
        {
            printf("quit send is error!/n");
            exit(1);
        }
        recvbytes=recv(control_sockfd,recvline,strlen(recvline),0);
        if(strncmp(recvline,"221",3)==0)
        {
            printf("221 bye!^_^");
            exit(1);
        }
        else
        {
            printf("quit recv is error!/n");
            exit(1);
        }
    }
    
    
    //mkd,在所在路径中创建目录 函数
    void ftp_creat_mkd(char *path,int control_sockfd)
    {
        char sendline[1024];
        char recvline[1024];
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        int recvbytes,sendbytes;
        int issuccess;
        strcat(sendline,"MKD ");
        strcat(sendline,path);
        strcat(sendline,"/r/n");
        printf("%s/n",sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("mkd send is error!");
            exit(1);
        }
        recvbytes=recv(control_sockfd,recvline,strlen(recvline),0);
        if(strncmp(recvline,"257",3)==0)
        {
            issuccess=1;
        }
        else
        {
            issuccess=0;
        }
    }
    
    
    //改变目录函数chdir
    void  ftp_changdir(char *dir,int control_sockfd)
    {
        
        char sendline[1024];
        char recvline[1024];
        int recvbytes,sendbytes;
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"CWD ");
        strcat(sendline,dir);
        strcat(sendline,"/r/n");
        printf("%s/n",sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("cwd send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            printf("cwd recv is error!/n");
        }
        if(strncmp(recvline,"250",3)==0)
        {
                    char buf[55];
                    snprintf(buf,39,">>> %s/n",recvline);
                    printf("%s/n",buf);
        }
        else
        {
            printf("cwd chdir is error!/n");
            exit(1);
        }
    }
    
    
    //pwd 命令函数
    //在应答中返回当前工作目录,“pwd”+/r/n
    void ftp_pwd(int control_sockfd)
    {
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"PWD");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("pwd,send is error/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,"257",3)==0)
        {
            int i=0;
            char *ptr;
            char currendir[1024];
            zeromery(currendir,1024);
            ptr=recvline+5;
            while(*(ptr)!='"')
            {
                currendir[i++]=*(ptr);
                ptr++;
            }
            currendir[i]='/0';
            printf("current directory is:%s/n",currendir);
    
        }
        else
        {
            printf("pwd,recv is error!/n");
        }
    }
    
    
    
    //获取服务器文件列表
    //list命令,是数据通道,通过的是21端口。the function 's struct is "the data //transport mode"(ascii or b) puls "the data mode to transport"(pasv or port//) puls "the list command"
    void ftp_list(int control_sockfd)
    {
        int pasv_or_port;// 定义the ftp协议的两种不同工作mode
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        struct sockaddr_in serv_addr;
        int i,j;
        int flag=0;
        int data_sockfd;
    
        //用户来选择pasv 或者是 port mode(默认的是pasv模式)
        char selectdata_mode_tran[1024];
        zeromery(selectdata_mode_tran,1024);
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        //printf("ftp->ftp协议工作方式选择(pasv or port)/n");
        //printf("ftp->");
    //    scanf("%s",selectdata_mode_tran);
        //if(strncmp(selectdata_mode_tran,"pasv",4)==0)
        //{
            pasv_or_port=0;
    //    }
    //    if(strncmp(selectdata_mode_tran,"port",4)==0)
    //    {
    //        pasv_or_port=1;
    //    }
        //pasv mode
        if(pasv_or_port==0)
        {
            strcat(sendline,"PASV");
            strcat(sendline,"/r/n");
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf("pasv send is error!/n");
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf("pasv recv is error!/n");
            }
            if(strncmp(recvline,"227",3)==0)
            {
                printf("%s/n",recvline);
            }
            else
            {
                printf("pasv recv is error!/n");
            }    
            //处理ftp server 端口
            char *ptr1,*ptr2;
            char num[1024];
            zeromery(num,1024);
            //取低位字节
            ptr1=recvline+strlen(recvline);
            while(*(ptr1)!=')')
            {
                ptr1--;
            }
            ptr2=ptr1;
            while(*(ptr2)!=',')
                ptr2--;
            strncpy(num,ptr2+1,ptr1-ptr2-1);
            i=atoi(num);//将字符串转换成整数
            //取高位字节
            zeromery(num,1024);
            ptr1=ptr2;
            ptr2--;
            while(*(ptr2)!=',')
                ptr2--;
            strncpy(num,ptr2+1,ptr1-ptr2-1);
            j=atoi(num);
            //初始化服务器数据连接时的端口信息
            int data_serviceport;
            data_serviceport=j*256+i;
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                    
            serv_addr.sin_family=AF_INET;
            serv_addr.sin_addr.s_addr=INADDR_ANY;
            serv_addr.sin_port=htons(data_serviceport);
            if(connect(data_sockfd,(struct sockaddr*)&serv;_addr,sizeof(struct sockaddr))==-1)
            {
                printf("pasv data connect is error!/n");
            }
        }
        //port mode
        if(pasv_or_port==1)
        {
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
            if(data_sockfd<0)
            {
                printf("创建数据端口连接失败!/n");
            }
            serv_addr.sin_family=AF_INET;
            serv_addr.sin_addr.s_addr=INADDR_ANY;
            serv_addr.sin_port=htons(SERV_PORT);
            
            int ret;
            int addrlen;
            ret=sizeof(struct sockaddr_in);
            getsockname(data_sockfd,(SA*)&serv;_addr,&ret;);
            
            //处理port 后面要带的参数
            char ip[1024];
            int i,j;
            char data[1024];
            zeromery(ip,1024);
            zeromery(data,1024);
            inet_ntop(AF_INET,&(serv_addr.sin_addr),ip,sizeof(ip));
            printf("%s/n",ip);
            i=data_sockfd/256;
            j=data_sockfd%256;
    
            //将点分十进制的点转换为逗号。
            char *ptr1;
            ptr1=ip;
            while(*(ptr1)!='/0')
            {
                if(*(ptr1)=='.')
                {
                    *(ptr1)=',';
                }
                ptr1++;
            }
    
            strcat(sendline,"PORT ");
            strcat(sendline,ip);
            strcat(sendline,",");
            strcat(sendline,itoa(i,data,10));
            strcat(sendline,",");
            strcat(sendline,itoa(j,data,10));
            strcat(sendline,"/r/n");
            printf("--->%s/n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf("port send is error!/n");
                exit(1);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"200",3)==0)
            {
                printf("%s/n",recvline);
            }
            else
            {
                printf("port recv is error!/n");
            }
    
        }
    
        //type
        zeromery(recvline,1024);
        zeromery(sendline,1024);
        strcat(sendline,"TYPE ");
        strcat(sendline,"I");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf(" type send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,"200",3)==0)
        {
            printf("使用二进制传输数据/n");
        }
        else
        {
            printf("type recv is error!/n");
        }
            
    
        //list
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"LIST");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("list send is error!/n");
        }
    recvdata:
        sleep(1);
        recvbytes=recv(data_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            close(data_sockfd);
            goto ending;
        }
        printf("%s",recvline);
        if(flag==0)
        {
            zeromery(recvline,1024);
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"226",3)!=0)
            {
                flag=1;
                goto recvdata;
            }
        }
    ending:
        if(flag!=1)
        {
            zeromery(recvline,1024);
        }
        close(data_sockfd);    
    }
    
    
    //itoa 函数的实现(整数转换成字符串)
    char *itoa(int value, char *string, int radix)
    {
        char tmp[33];
        char *tp = tmp;
        int i;
        unsigned v;
        int sign;
        char *sp;
    
        sign = (radix == 10 && value < 0);
        if (sign)
            v = -value;
        else
            v = (unsigned)value;
        while (v || tp == tmp)
        {
            i = v % radix;
            v = v / radix;
            if (i < 10)
              *tp++ = i+'0';
            else
              *tp++ = i + 'a' - 10;
        }
    
        if (string == 0)
            string = (char *)malloc((tp-tmp)+sign+1);
        sp = string;
    
        if (sign)
            *sp++ = '-';
        while (tp > tmp)
            *sp++ = *--tp;
        *sp = 0;
        return string;
    }
    
    
    //back 返回上一级函数,相当于cd /;
    void ftp_back(int control_sockfd)
    {
        char sendline[1024],recvline[1024];
        int recvbytes,sendbytes;
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"CDUP");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("cdup send is error !/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            printf("cdup recv is error !/n");
        }
        if(strncmp(recvline,"250",3)==0)
        {
            printf("请求的文件操作已经成功/n");
        }
    }
    //stru命令的实现
    void ftp_stru(int control_sockfd)
    {
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"STRU");
        strcat(sendline,"F");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("stru send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            printf("stru recv is error!/n");
        }
        if(strncmp(recvline,"200",3)==0)
        {
            f=0;
        }
    
    }
    
    //断点函数的支持
    void ftp_rest(int control_sockfd)
    {
    
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,"REST ");
        strcat(sendline,"500");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf("stru send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            printf("stru recv is error!/n");
        }
        if(strncmp(recvline,"350",3)==0)
        {
            printf("%s/n",recvline);
        }
    }
    
    //下载的实现函数
    int ftp_download(int control_sockfd)
    {
        
        int pasv_or_port;// 定义the ftp协议的两种不同工作mode
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        struct sockaddr_in serv_addr;
        FILE *fd;
        int i,j;
        int data_sockfd;
        //rest
        ftp_rest(control_sockfd);
        //type
        zeromery(recvline,1024);
        zeromery(sendline,1024);
        strcat(sendline,"TYPE ");
        strcat(sendline,"I");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
                printf(" type send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,"200",3)==0)
        {
            printf("使用二进制传输数据/n");
        }
        else
        {
            printf("type recv is error!/n");
        }
    
        if(npsupport==1)
        {
            //open the file
            int size;
            char localpathname[60];//预打开的文件路径字符串
            int flags;
            char pathname[60];
            unsigned int mode;
            //用户来选择pasv 或者是 port mode
            char selectdata_mode_tran[1024];
            zeromery(selectdata_mode_tran,1024);
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            pasv_or_port=0;//(默认是pasv模式)
            //pasv mode
            if(pasv_or_port==0)
            {
                strcat(sendline,"PASV");
                strcat(sendline,"/r/n");
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("pasv send is error!/n");
                }
                zeromery(recvline,1024);
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(recvbytes<0)
                {
                    printf("pasv recv is error!/n");
                }
                if(strncmp(recvline,"227",3)==0)
                {
                    char buf[55];
                    snprintf(buf,51,">>> %s/n",recvline);
                    printf("%s/n",buf);
                }
                else
                {
                    printf("pasv recv is error!/n");
                }    
                //处理ftp server 端口
                char *ptr1,*ptr2;
                char num[1024];
                zeromery(num,1024);
                //取低位字节
                ptr1=recvline+strlen(recvline);
                while(*(ptr1)!=')')
                {
                    ptr1--;
                }
                ptr2=ptr1;
                while(*(ptr2)!=',')
                    ptr2--;
                strncpy(num,ptr2+1,ptr1-ptr2-1);
                i=atoi(num);//将字符串转换成整数
                //取高位字节
                zeromery(num,1024);
                ptr1=ptr2;
                ptr2--;
                while(*(ptr2)!=',')
                    ptr2--;
                strncpy(num,ptr2+1,ptr1-ptr2-1);
                j=atoi(num);
                //初始化服务器数据连接时的端口信息
                int data_serviceport;
                data_serviceport=j*256+i;
                data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                    
                serv_addr.sin_family=AF_INET;
                serv_addr.sin_addr.s_addr=INADDR_ANY;
                serv_addr.sin_port=htons(data_serviceport);
                if(connect(data_sockfd,(struct sockaddr*)&serv;_addr,sizeof(struct sockaddr))==-1)
                {
                    printf("pasv data connect is error!/n");
                }
                printf("remote-file-pathname=");
                scanf("%s",pathname);
                printf("local-file-pathname=");
                scanf("%s",localpathname);
                printf("local:%s remore:%s/n",localpathname,pathname);
                fd=fopen(localpathname,"w+");
                if(fd==NULL)
                {
                    printf("cannot open file/n");
                    exit(1);
                }
    
        
                //send the command retr;
                zeromery(sendline,1024);
                zeromery(recvline,1024);
                strcat(sendline,"RETR ");
                strcat(sendline,pathname);
                strcat(sendline,"/r/n");
                printf("%s/n",sendline);
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("retr send is error!/n");
                }
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(recvbytes<0)
                {
                    printf("retr recv is error!/n");
                }
                if(strncmp(recvline,"400",3)>0)
                {
                    printf("return is error!/n");
                }
            }
            //port mode
            /*if(pasv_or_port==1)
            {
                data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                if(data_sockfd<0)
                {
                    printf("创建数据端口连接失败!/n");
                }
                serv_addr.sin_family=AF_INET;
                serv_addr.sin_addr.s_addr=INADDR_ANY;
                serv_addr.sin_port=htons(SERV_PORT);
            
                int ret;
                int addrlen;
                ret=sizeof(struct sockaddr_in);
                getsockname(data_sockfd,(SA*)&serv;_addr,&ret;);
            
                //处理port 后面要带的参数
                char ip[1024];
                int i,j;
                char data[1024];
                zeromery(ip,1024);
                zeromery(data,1024);
                inet_ntop(AF_INET,&(serv_addr.sin_addr),ip,sizeof(ip));
                printf("%s/n",ip);
                i=data_sockfd/256;
                j=data_sockfd%256;
    
                //将点分十进制的点转换为逗号。
                char *ptr1;
                ptr1=ip;
                while(*(ptr1)!='/0')
                {
                    if(*(ptr1)=='.')
                    {
                        *(ptr1)=',';
                    }
                    ptr1++;
                }
    
                strcat(sendline,"PORT ");
                strcat(sendline,ip);
                strcat(sendline,",");
                strcat(sendline,itoa(i,data,10));
                strcat(sendline,",");
                strcat(sendline,itoa(j,data,10));
                strcat(sendline,"/r/n");
                printf("--->%s/n",sendline);
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("port send is error!/n");
                    exit(1);
                }
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(strncmp(recvline,"200",3)==0)
                {
                    printf("%s/n",recv);
                }
                else
                {
                    printf("port recv is error!/n");
                }
    
            }*/
            //begin to transpotr data
            sleep(1);
            int flag=0;
            char buffer[65536];
    recvdata:
            zeromery(buffer,1024);
            recvbytes=recv(data_sockfd,buffer,sizeof(buffer),0);
            if(recvbytes<0)
            {
                close(data_sockfd);
                goto end;
            }
            fwrite(buffer,1,recvbytes,fd);
            zeromery(recvline,1024);
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(flag==0)
            {
                if(strncmp(recvline,"226",3)!=0)
                {
                        flag=1;
                        goto recvdata;
                }
            }
    end:
            if(flag!=1)
            {
                zeromery(recvline,1024);
                shutdown(data_sockfd,SHUT_WR);
                close(data_sockfd);
            }
            close(data_sockfd);
    /*    int err;
        char buffer[65535];
        err=read(data_sockfd,buffer,sizeof(buffer));
        sleep(5);
        fwrite(buffer,1,err,fd);
        sleep(5);
        zeromery(recvline,1024);
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,"226",3)==0)
        {
        end:    printf("226 transfer complete/n");
            close(data_sockfd);
        }*/
        return 0;
        }
    }
    
    
    //up 函数
    int ftp_up(int control_sockfd)
    {
            
        int pasv_or_port;// 定义the ftp协议的两种不同工作mode
        int recvbytes,sendbytes;
        char sendline[1024],recvline[1024];
        struct sockaddr_in serv_addr;
        FILE *fd;
        int i,j;
        int data_sockfd;
        //type
        zeromery(recvline,1024);
        zeromery(sendline,1024);
        strcat(sendline,"TYPE ");
        strcat(sendline,"I");
        strcat(sendline,"/r/n");
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
                printf(" type send is error!/n");
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,"200",3)==0)
        {
            printf("使用二进制传输数据/n");
        }
        else
        {
            printf("type recv is error!/n");
        }
    
        if(npsupport==1)
        {
            //open the file
            int size;
            char localpathname[60];//预打开的文件路径字符串
            int flags;
            char pathname[60];
            unsigned int mode;
            //用户来选择pasv 或者是 port mode
            char selectdata_mode_tran[1024];
            zeromery(selectdata_mode_tran,1024);
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            pasv_or_port=0;//(默认是pasv模式)
            //pasv mode
            if(pasv_or_port==0)
            {
                strcat(sendline,"PASV");
                strcat(sendline,"/r/n");
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("pasv send is error!/n");
                }
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(recvbytes<0)
                {
                    printf("pasv recv is error!/n");
                }
                if(strncmp(recvline,"227",3)==0)
                {
                    char buf[55];
                    snprintf(buf,51,">>> %s/n",recvline);
                    printf("%s/n",buf);
                }
                else
                {
                    printf("pasv recv is error!/n");
                }    
                //处理ftp server 端口
                char *ptr1,*ptr2;
                char num[1024];
                zeromery(num,1024);
                //取低位字节
                ptr1=recvline+strlen(recvline);
                while(*(ptr1)!=')')
                {
                    ptr1--;
                }
                ptr2=ptr1;
                while(*(ptr2)!=',')
                    ptr2--;
                strncpy(num,ptr2+1,ptr1-ptr2-1);
                i=atoi(num);//将字符串转换成整数
                //取高位字节
                zeromery(num,1024);
                ptr1=ptr2;
                ptr2--;
                while(*(ptr2)!=',')
                    ptr2--;
                strncpy(num,ptr2+1,ptr1-ptr2-1);
                j=atoi(num);
                //初始化服务器数据连接时的端口信息
                int data_serviceport;
                data_serviceport=j*256+i;
                data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                    
                serv_addr.sin_family=AF_INET;
                serv_addr.sin_addr.s_addr=INADDR_ANY;
                serv_addr.sin_port=htons(data_serviceport);
                if(connect(data_sockfd,(struct sockaddr*)&serv;_addr,sizeof(struct sockaddr))==-1)
                {
                    printf("pasv data connect is error!/n");
                }
                    printf("local-file-pathname=");
                    scanf("%s",pathname);
                    printf("remote-file-pathname=");
                    scanf("%s",localpathname);
                    printf("local:%s remore:%s/n",localpathname,pathname);
                    fd=fopen(pathname,"r");
                    if(fd==NULL)
                    {
                        printf("cannot open file,请重新输入!/n");
                    }
    
                //send the command retr;
                zeromery(sendline,1024);
                zeromery(recvline,1024);
                strcat(sendline,"STOR ");
                strcat(sendline,localpathname);
                strcat(sendline,"/r/n");
                printf("%s/n",sendline);
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("stor send is error!/n");
                }
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(recvbytes<0)
                {
                    printf("retr recv is error!/n");
                }
                if(strncmp(recvline,"150",3)==0)
                {
                    char buf[55];
                    snprintf(buf,25,">>> %s/n",recvline);
                    printf("%s/n",buf);
                }
            }
            //port mode
            /*if(pasv_or_port==1)
            {
                data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                if(data_sockfd<0)
                {
                    printf("创建数据端口连接失败!/n");
                }
                serv_addr.sin_family=AF_INET;
                serv_addr.sin_addr.s_addr=INADDR_ANY;
                serv_addr.sin_port=htons(SERV_PORT);
            
                int ret;
                int addrlen;
                ret=sizeof(struct sockaddr_in);
                getsockname(data_sockfd,(SA*)&serv;_addr,&ret;);
            
                //处理port 后面要带的参数
                char ip[1024];
                int i,j;
                char data[1024];
                zeromery(ip,1024);
                zeromery(data,1024);
                inet_ntop(AF_INET,&(serv_addr.sin_addr),ip,sizeof(ip));
                printf("%s/n",ip);
                i=data_sockfd/256;
                j=data_sockfd%256;
    
                //将点分十进制的点转换为逗号。
                char *ptr1;
                ptr1=ip;
                while(*(ptr1)!='/0')
                {
                    if(*(ptr1)=='.')
                    {
                        *(ptr1)=',';
                    }
                    ptr1++;
                }
    
                strcat(sendline,"PORT ");
                strcat(sendline,ip);
                strcat(sendline,",");
                strcat(sendline,itoa(i,data,10));
                strcat(sendline,",");
                strcat(sendline,itoa(j,data,10));
                strcat(sendline,"/r/n");
                printf("--->%s/n",sendline);
                sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
                if(sendbytes<0)
                {
                    printf("port send is error!/n");
                    exit(1);
                }
                recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
                if(strncmp(recvline,"200",3)==0)
                {
                    printf("%s/n",recv);
                }
                else
                {
                    printf("port recv is error!/n");
                }
    
            }*/
            //begin to transpotr data
        while(!feof(fd))
        {        
            char buffer[65536];
            zeromery(buffer,sizeof(buffer));
            int size;
            size=fread(buffer,1,sizeof(buffer),fd);
            if(ferror(fd))
            {
                printf("read file data is error!/n");
                break;
            }
            else
            {
                zeromery(sendline,1024);
                sendbytes=send(data_sockfd,buffer,size,0);
                printf("传输了 %d 个字节/n",sendbytes);
            }
            close(data_sockfd);
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"226",3)==0)
            {
                printf("226 transfer complete");
                break;
            }
        }
        return 0;
        }
    }







沪ICP备19023445号-2号
友情链接