设为首页 收藏本站
查看: 963|回复: 0

[经验分享] ftp协议c语言实现-linux平台

[复制链接]

尚未签到

发表于 2015-11-6 08:02:52 | 显示全部楼层 |阅读模式
  /*有丰富的注释,很好理解,这是我自己第一次写linux中的网络协议。
* =====================================================================================
*
*       Filename:  ftpclient.c
*
*    Description:  ftpclient 能上传下载,断点,list 列表等基本的简单东西。下载的时候有时会出现下载不全的问题
  *    如果大家能解决,请给我留言,或者回复,也可发送到下面的邮箱里面。谢谢!让我们一同进步!
*
*        Version:  1.0
*        Created:  2010年08月04日 08时40分15秒
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  Yang Shao Kun (), cdutyangshaokun@163.com
*        Company:  College of Information Engineering of CDUT
*
* =====================================================================================
*/
#include<stdio.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<strings.h>
#include<unistd.h>
#include<netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#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(&quot;ftp>&quot;);
    char command[MAXSIZE];
    char*cmd;
    scanf(&quot;%s&quot;,command);
    cmd=command;
    while(*(cmd)==' ')
        cmd++;

    if(strncmp(cmd,&quot;login&quot;,5)==0)
    {
        login();
        if(login_yes==1)
        {
            while(1)
            {
            comm:            
                sleep(1);
                printf(&quot;ftp>&quot;);
                zeromery(command,1024);
                scanf(&quot;%s&quot;,command);
                cmd=command;
                while(*(cmd)==' ')
                cmd++;
                if(strncmp(cmd,&quot;pasv&quot;,4)==0)
                {
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,&quot;port&quot;,4)==0)
                {
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,&quot;list&quot;,4)==0)
                {
                    ftp_pwd(control_sockfd);
                    ftp_list(control_sockfd);
                }
                if(strncmp(cmd,&quot;pwd&quot;,3)==0)
                {
                    ftp_pwd(control_sockfd);
                }
                if(strncmp(cmd,&quot;mkdir&quot;,5)==0)
                {
                    char path[60];
                    zeromery(path,60);
                    printf(&quot;创建的路径名: &quot;);
                    scanf(&quot;%s&quot;,path);
                    printf(&quot;s/n&quot;,path);
                    ftp_creat_mkd(path,control_sockfd);
                }
                if(strncmp(cmd,&quot;back&quot;,4)==0)
                {
                    ftp_back(control_sockfd);

                    ftp_pwd(control_sockfd);
                }
                if(strncmp(cmd,&quot;cd&quot;,2)==0)
                {
                    int i;
                    char path[60];
                    zeromery(path,60);
                    printf(&quot;要到的路径:&quot;);
                    scanf(&quot;%s&quot;,path);
                    printf(&quot;%s/n&quot;,path);
                    ftp_changdir(path,control_sockfd);
                }
                if(strncmp(cmd,&quot;get&quot;,3)==0)
                {
                    ftp_pwd(control_sockfd);   
                    ftp_download(control_sockfd);
                }
                if(strncmp(cmd,&quot;up&quot;,3)==0)
                {
                    ftp_pwd(control_sockfd);
                    ftp_up(control_sockfd);        
                }
                if(strncmp(cmd,&quot;quit&quot;,4)==0)
                {
                    printf(&quot;bye^_^/n&quot;);
                    close(control_sockfd);
                    break;
                }
                printf(&quot;支持 list,pwd,mkdir,back,cd,up,get/n&quot;);   
        }
        
    }
    else if(login_yes==0)
    {
        int i;//不成功登录下最多还有两次机会,如果不能在两次登录,则,关闭链接。
        printf(&quot;Can not login vsftpd&quot;);
        for(i=2;i>0;i--)
        {
            printf(&quot;你还有 %d 登录机会/n&quot;,i);            
            login();
            if(login_yes==1)
            {
                goto comm;
            }
        }
        if(i==0)
        {
            printf(&quot;你不能在登录!/n&quot;);
            close(control_sockfd);
        }
            
    }
    else if (strncmp(cmd,&quot;quit&quot;,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(&quot;please enter the hostname/n&quot;);
    printf(&quot;ftp-> &quot;);
    scanf(&quot;%s&quot;,name);
    host=gethostbyname(name);
    if(host==NULL)
    {
        printf(&quot;get host by name is error!/n&quot;);
        login_yes=0;
    }
    else
    {
        //创建socket
        control_sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(control_sockfd<0)
        {
            printf(&quot;socket is error/n&quot;);
            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(&quot;connect is error/n&quot;);
            login_yes=0;
        }
        printf(&quot;connect to %s/n&quot;,inet_ntop(AF_INET,host->h_addr,addr,1024));
        recvdate=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvdate==-1)
        {
            printf(&quot;recvdate is connect error/n&quot;);
            login_yes=0;
        }
        else if(strncmp(recvline,&quot;220&quot;,3)==0)
        {
            printf(&quot;connect success,pelase enter username/n&quot;);
            login_yes=1;
        }
        else
        {
            printf(&quot;220 connect is error!&quot;);
            login_yes=0;   
        }

        //ftp用户登录主体部分
        int sendbytes,recvbytes;
        zeromery(name,1024);
        zeromery(password,1024);
        zeromery(recvline,1024);
        zeromery(sendline,1024);
        printf(&quot;ftp-> &quot;);
        scanf(&quot;%s&quot;,name);//可以支持匿名登录vsftpd
        strcat(sendline,&quot;USER &quot;);
        strcat(sendline,name);
        strcat(sendline,&quot;/r/n&quot;);
        printf(&quot;--->%s/n&quot;,sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes==-1)
        {
            printf(&quot;send is wrong/n&quot;);
            login_yes=0;
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,&quot;331&quot;,3)==0)
        {
            printf(&quot;331 please specify the password./n&quot;);
        }
        else
        {
            printf(&quot;recv date is error./n&quot;);
            login_yes=0;
        }
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        printf(&quot;ftp-> &quot;);
        scanf(&quot;%s&quot;,password);
        strcat(sendline,&quot;PASS &quot;);
        strcat(sendline,password);
        strcat(sendline,&quot;/r/n&quot;);
        printf(&quot;--->%s/n&quot;,sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes==-1)
        {
            printf(&quot;pass send is error/n&quot;);
            login_yes=0;
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,&quot;230&quot;,3)==0)
        {
            printf(&quot;login success!/n&quot;);
            login_yes=1;
        }
        else
        {
            printf(&quot;pass recv is error/n&quot;);
            login_yes=0;
        }


        //支持断点续传
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        strcat(sendline,&quot;REST &quot;);
        strcat(sendline,&quot;0&quot;);
        strcat(sendline,&quot;/r/n&quot;);
        printf(&quot;--->%s/n&quot;,sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes==-1)
        {
            printf(&quot;rest send is error!/n&quot;);
            login_yes=0;
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes==-1)
        {
            printf(&quot;rest recv date is error./n&quot;);   
            login_yes=0;   
        }
        if(strncmp(recvline,&quot;350 Restart position accepted (0).&quot;,34)==0)
        {
            npsupport=1;
            printf(&quot;support 断点续传/n&quot;);
            login_yes=1;
        }
        else
        {
            npsupport=0;
            printf(&quot;not support 断点续传/n&quot;);
            login_yes=0;   
        }
   

        //获取服务器版本信息
        zeromery(recvline,1024);
        zeromery(sendline,1024);
        strcat(sendline,&quot;SYST&quot;);
        strcat(sendline,&quot;/r/n&quot;);
        printf(&quot;--->%s/n&quot;,sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes==-1)
        {
            printf(&quot;syst send is error/n&quot;);
            login_yes=0;
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes==-1)
        {
            printf(&quot;syst recv is error/n&quot;);
            login_yes=0;
        }
        if(strncmp(recvline,&quot;215 UNIX Type: L8&quot;,17)==0)
        {
            printf(&quot;%s&quot;,recvline);
            login_yes=1;
        }
        else
        {
            printf(&quot;syst recv connectin is error/n&quot;);
            login_yes=0;
        }   
    }
   
    return login_yes;
}

//数组初始化
void zeromery(char *a,int len)
{
    int i;
    len=sizeof(a);
    for(i=0;i<len;i++)
    {
        a=0;
    }
}

//quit函数,control_sockfd,通过实参传递
void ftp_quit(int control_sockfd )
{
    char sendline[1024];
    char recvline[1024];
    int recvbytes;
    int sendbytes;
    zeromery(sendline,1024);
    zeromery(recvline,1024);
    strcat(sendline,&quot;QUIT&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;quit send is error!/n&quot;);
        exit(1);
    }
    recvbytes=recv(control_sockfd,recvline,strlen(recvline),0);
    if(strncmp(recvline,&quot;221&quot;,3)==0)
    {
        printf(&quot;221 bye!^_^&quot;);
        exit(1);
    }
    else
    {
        printf(&quot;quit recv is error!/n&quot;);
        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,&quot;MKD &quot;);
    strcat(sendline,path);
    strcat(sendline,&quot;/r/n&quot;);
    printf(&quot;%s/n&quot;,sendline);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;mkd send is error!&quot;);
        exit(1);
    }
    recvbytes=recv(control_sockfd,recvline,strlen(recvline),0);
    if(strncmp(recvline,&quot;257&quot;,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,&quot;CWD &quot;);
    strcat(sendline,dir);
    strcat(sendline,&quot;/r/n&quot;);
    printf(&quot;%s/n&quot;,sendline);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;cwd send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(recvbytes<0)
    {
        printf(&quot;cwd recv is error!/n&quot;);
    }
    if(strncmp(recvline,&quot;250&quot;,3)==0)
    {
                char buf[55];
                snprintf(buf,39,&quot;>>> %s/n&quot;,recvline);
                printf(&quot;%s/n&quot;,buf);
    }
    else
    {
        printf(&quot;cwd chdir is error!/n&quot;);
        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,&quot;PWD&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;pwd,send is error/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,&quot;257&quot;,3)==0)
    {
        int i=0;
        char *ptr;
        char currendir[1024];
        zeromery(currendir,1024);
        ptr=recvline+5;
        while(*(ptr)!='&quot;')
        {
            currendir[i++]=*(ptr);
            ptr++;
        }
        currendir='/0';
        printf(&quot;current directory is:%s/n&quot;,currendir);

    }
    else
    {
        printf(&quot;pwd,recv is error!/n&quot;);
    }
}



//获取服务器文件列表
//list命令,是数据通道,通过的是21端口。the function 's struct is &quot;the data //transport mode&quot;(ascii or b) puls &quot;the data mode to transport&quot;(pasv or port//) puls &quot;the list command&quot;
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(&quot;ftp->ftp协议工作方式选择(pasv or port)/n&quot;);
    //printf(&quot;ftp->&quot;);
//    scanf(&quot;%s&quot;,selectdata_mode_tran);
    //if(strncmp(selectdata_mode_tran,&quot;pasv&quot;,4)==0)
    //{
        pasv_or_port=0;
//    }
//    if(strncmp(selectdata_mode_tran,&quot;port&quot;,4)==0)
//    {
//        pasv_or_port=1;
//    }
    //pasv mode
    if(pasv_or_port==0)
    {
        strcat(sendline,&quot;PASV&quot;);
        strcat(sendline,&quot;/r/n&quot;);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf(&quot;pasv send is error!/n&quot;);
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(recvbytes<0)
        {
            printf(&quot;pasv recv is error!/n&quot;);
        }
        if(strncmp(recvline,&quot;227&quot;,3)==0)
        {
            printf(&quot;%s/n&quot;,recvline);
        }
        else
        {
            printf(&quot;pasv recv is error!/n&quot;);
        }   
        //处理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(&quot;pasv data connect is error!/n&quot;);
        }
    }
    //port mode
    if(pasv_or_port==1)
    {
        data_sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(data_sockfd<0)
        {
            printf(&quot;创建数据端口连接失败!/n&quot;);
        }
        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(&quot;%s/n&quot;,ip);
        i=data_sockfd/256;
        j=data_sockfd%256;

        //将点分十进制的点转换为逗号。
        char *ptr1;
        ptr1=ip;
        while(*(ptr1)!='/0')
        {
            if(*(ptr1)=='.')
            {
                *(ptr1)=',';
            }
            ptr1++;
        }

        strcat(sendline,&quot;PORT &quot;);
        strcat(sendline,ip);
        strcat(sendline,&quot;,&quot;);
        strcat(sendline,itoa(i,data,10));
        strcat(sendline,&quot;,&quot;);
        strcat(sendline,itoa(j,data,10));
        strcat(sendline,&quot;/r/n&quot;);
        printf(&quot;--->%s/n&quot;,sendline);
        sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
        if(sendbytes<0)
        {
            printf(&quot;port send is error!/n&quot;);
            exit(1);
        }
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,&quot;200&quot;,3)==0)
        {
            printf(&quot;%s/n&quot;,recvline);
        }
        else
        {
            printf(&quot;port recv is error!/n&quot;);
        }

    }

    //type
    zeromery(recvline,1024);
    zeromery(sendline,1024);
    strcat(sendline,&quot;TYPE &quot;);
    strcat(sendline,&quot;I&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot; type send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,&quot;200&quot;,3)==0)
    {
        printf(&quot;使用二进制传输数据/n&quot;);
    }
    else
    {
        printf(&quot;type recv is error!/n&quot;);
    }
        

    //list
    zeromery(sendline,1024);
    zeromery(recvline,1024);
    strcat(sendline,&quot;LIST&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;list send is error!/n&quot;);
    }
recvdata:
    sleep(1);
    recvbytes=recv(data_sockfd,recvline,sizeof(recvline),0);
    if(recvbytes<0)
    {
        close(data_sockfd);
        goto ending;
    }
    printf(&quot;%s&quot;,recvline);
    if(flag==0)
    {
        zeromery(recvline,1024);
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,&quot;226&quot;,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,&quot;CDUP&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;cdup send is error !/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(recvbytes<0)
    {
        printf(&quot;cdup recv is error !/n&quot;);
    }
    if(strncmp(recvline,&quot;250&quot;,3)==0)
    {
        printf(&quot;请求的文件操作已经成功/n&quot;);
    }
}
//stru命令的实现
void ftp_stru(int control_sockfd)
{
    int recvbytes,sendbytes;
    char sendline[1024],recvline[1024];
    zeromery(sendline,1024);
    zeromery(recvline,1024);
    strcat(sendline,&quot;STRU&quot;);
    strcat(sendline,&quot;F&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;stru send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(recvbytes<0)
    {
        printf(&quot;stru recv is error!/n&quot;);
    }
    if(strncmp(recvline,&quot;200&quot;,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,&quot;REST &quot;);
    strcat(sendline,&quot;500&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
        printf(&quot;stru send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(recvbytes<0)
    {
        printf(&quot;stru recv is error!/n&quot;);
    }
    if(strncmp(recvline,&quot;350&quot;,3)==0)
    {
        printf(&quot;%s/n&quot;,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,&quot;TYPE &quot;);
    strcat(sendline,&quot;I&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
            printf(&quot; type send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,&quot;200&quot;,3)==0)
    {
        printf(&quot;使用二进制传输数据/n&quot;);
    }
    else
    {
        printf(&quot;type recv is error!/n&quot;);
    }

    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,&quot;PASV&quot;);
            strcat(sendline,&quot;/r/n&quot;);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;pasv send is error!/n&quot;);
            }
            zeromery(recvline,1024);
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf(&quot;pasv recv is error!/n&quot;);
            }
            if(strncmp(recvline,&quot;227&quot;,3)==0)
            {
                char buf[55];
                snprintf(buf,51,&quot;>>> %s/n&quot;,recvline);
                printf(&quot;%s/n&quot;,buf);
            }
            else
            {
                printf(&quot;pasv recv is error!/n&quot;);
            }   
            //处理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(&quot;pasv data connect is error!/n&quot;);
            }
            printf(&quot;remote-file-pathname=&quot;);
            scanf(&quot;%s&quot;,pathname);
            printf(&quot;local-file-pathname=&quot;);
            scanf(&quot;%s&quot;,localpathname);
            printf(&quot;local:%s remore:%s/n&quot;,localpathname,pathname);
            fd=fopen(localpathname,&quot;w+&quot;);
            if(fd==NULL)
            {
                printf(&quot;cannot open file/n&quot;);
                exit(1);
            }

   
            //send the command retr;
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            strcat(sendline,&quot;RETR &quot;);
            strcat(sendline,pathname);
            strcat(sendline,&quot;/r/n&quot;);
            printf(&quot;%s/n&quot;,sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;retr send is error!/n&quot;);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf(&quot;retr recv is error!/n&quot;);
            }
            if(strncmp(recvline,&quot;400&quot;,3)>0)
            {
                printf(&quot;return is error!/n&quot;);
            }
        }
        //port mode
        /*if(pasv_or_port==1)
        {
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
            if(data_sockfd<0)
            {
                printf(&quot;创建数据端口连接失败!/n&quot;);
            }
            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(&quot;%s/n&quot;,ip);
            i=data_sockfd/256;
            j=data_sockfd%256;

            //将点分十进制的点转换为逗号。
            char *ptr1;
            ptr1=ip;
            while(*(ptr1)!='/0')
            {
                if(*(ptr1)=='.')
                {
                    *(ptr1)=',';
                }
                ptr1++;
            }

            strcat(sendline,&quot;PORT &quot;);
            strcat(sendline,ip);
            strcat(sendline,&quot;,&quot;);
            strcat(sendline,itoa(i,data,10));
            strcat(sendline,&quot;,&quot;);
            strcat(sendline,itoa(j,data,10));
            strcat(sendline,&quot;/r/n&quot;);
            printf(&quot;--->%s/n&quot;,sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;port send is error!/n&quot;);
                exit(1);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,&quot;200&quot;,3)==0)
            {
                printf(&quot;%s/n&quot;,recv);
            }
            else
            {
                printf(&quot;port recv is error!/n&quot;);
            }

        }*/
        //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,&quot;226&quot;,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,&quot;226&quot;,3)==0)
    {
    end:    printf(&quot;226 transfer complete/n&quot;);
        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,&quot;TYPE &quot;);
    strcat(sendline,&quot;I&quot;);
    strcat(sendline,&quot;/r/n&quot;);
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
            printf(&quot; type send is error!/n&quot;);
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,&quot;200&quot;,3)==0)
    {
        printf(&quot;使用二进制传输数据/n&quot;);
    }
    else
    {
        printf(&quot;type recv is error!/n&quot;);
    }

    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,&quot;PASV&quot;);
            strcat(sendline,&quot;/r/n&quot;);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;pasv send is error!/n&quot;);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf(&quot;pasv recv is error!/n&quot;);
            }
            if(strncmp(recvline,&quot;227&quot;,3)==0)
            {
                char buf[55];
                snprintf(buf,51,&quot;>>> %s/n&quot;,recvline);
                printf(&quot;%s/n&quot;,buf);
            }
            else
            {
                printf(&quot;pasv recv is error!/n&quot;);
            }   
            //处理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(&quot;pasv data connect is error!/n&quot;);
            }
                printf(&quot;local-file-pathname=&quot;);
                scanf(&quot;%s&quot;,pathname);
                printf(&quot;remote-file-pathname=&quot;);
                scanf(&quot;%s&quot;,localpathname);
                printf(&quot;local:%s remore:%s/n&quot;,localpathname,pathname);
                fd=fopen(pathname,&quot;r&quot;);
                if(fd==NULL)
                {
                    printf(&quot;cannot open file,请重新输入!/n&quot;);
                }

            //send the command retr;
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            strcat(sendline,&quot;STOR &quot;);
            strcat(sendline,localpathname);
            strcat(sendline,&quot;/r/n&quot;);
            printf(&quot;%s/n&quot;,sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;stor send is error!/n&quot;);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf(&quot;retr recv is error!/n&quot;);
            }
            if(strncmp(recvline,&quot;150&quot;,3)==0)
            {
                char buf[55];
                snprintf(buf,25,&quot;>>> %s/n&quot;,recvline);
                printf(&quot;%s/n&quot;,buf);
            }
        }
        //port mode
        /*if(pasv_or_port==1)
        {
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
            if(data_sockfd<0)
            {
                printf(&quot;创建数据端口连接失败!/n&quot;);
            }
            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(&quot;%s/n&quot;,ip);
            i=data_sockfd/256;
            j=data_sockfd%256;

            //将点分十进制的点转换为逗号。
            char *ptr1;
            ptr1=ip;
            while(*(ptr1)!='/0')
            {
                if(*(ptr1)=='.')
                {
                    *(ptr1)=',';
                }
                ptr1++;
            }

            strcat(sendline,&quot;PORT &quot;);
            strcat(sendline,ip);
            strcat(sendline,&quot;,&quot;);
            strcat(sendline,itoa(i,data,10));
            strcat(sendline,&quot;,&quot;);
            strcat(sendline,itoa(j,data,10));
            strcat(sendline,&quot;/r/n&quot;);
            printf(&quot;--->%s/n&quot;,sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf(&quot;port send is error!/n&quot;);
                exit(1);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,&quot;200&quot;,3)==0)
            {
                printf(&quot;%s/n&quot;,recv);
            }
            else
            {
                printf(&quot;port recv is error!/n&quot;);
            }

        }*/
        //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(&quot;read file data is error!/n&quot;);
            break;
        }
        else
        {
            zeromery(sendline,1024);
            sendbytes=send(data_sockfd,buffer,size,0);
            printf(&quot;传输了 %d 个字节/n&quot;,sendbytes);
        }
        close(data_sockfd);
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(strncmp(recvline,&quot;226&quot;,3)==0)
        {
            printf(&quot;226 transfer complete&quot;);
            break;
        }
    }
    return 0;
    }
}
             版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-135614-1-1.html 上篇帖子: 解决ftp上传遇到的227错误 下篇帖子: Ftp数据传输
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表