zoukankan      html  css  js  c++  java
  • ftp客户端的创建

    1.本段代码采用了 select I/O端口复用

    2.含有三种功能:ls,  上传文件, 下载文件。这是拷贝别人的代码,自己添加了注释,随后会进行修改,

      自己需要的功能:上传文件, 下载文件,  (并且在传输途中,对所有的文件进行openssl加密)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <netdb.h>
      4 #include <errno.h>
      5 #include <sys/types.h>
      6 #include <sys/stat.h>
      7 #include <fcntl.h>
      8 #include <unistd.h>
      9 #include <string.h>
     10 #include <sys/ioctl.h>
     11 #include <sys/fcntl.h>
     12 
     13 
     14 #define MAXBUF             1024        //宏大小
     15 #define STDIN_FILENO     1            //标准输入
     16 #define STDOUT_FILENO     0            //标准输出
     17 
     18 
     19 #define USERNAME     220            //用户名
     20 #define PASSWORD      331            //密码
     21 #define LOGIN           230            //登录
     22 #define PATHNAME      257            //路径名
     23 #define CLOSEDATA     226            //    
     24 #define ACTIONOK      250            //
     25 
     26 
     27 char *rbuf,*rbuf1,*wbuf,*wbuf1;
     28 
     29 
     30 char filename[100];                    //文件名
     31 char *host;                            //要连接的服务器地址
     32 
     33 
     34 struct sockaddr_in servaddr;        //服务器的地址、端口结构体
     35 
     36 //1.第一步,打开一个TCP链接
     37 int cliopen(char *host,int port);
     38 //
     39 int strtosrv(char *str);
     40 int ftp_get(int sck,char *pDownloadFileName);
     41 int ftp_put(int sck,char *pUploadFileName_s);
     42 void cmd_tcp(int sockfd);                        //
     43 
     44 //主函数
     45 int main(int argc,char *argv[])
     46 {
     47     int fd;
     48 
     49     //判断输入参数
     50     if(0 != argc -2)
     51     {
     52         printf("%s
    ","missing <hostname>");
     53         exit(0);
     54     }
     55 
     56     //指定服务器地址
     57     host = argv[1];
     58     //指定端口
     59     int port = 21;
     60    
     61     rbuf = (char *)malloc(MAXBUF*sizeof(char));
     62     rbuf1 = (char *)malloc(MAXBUF*sizeof(char));
     63     wbuf = (char *)malloc(MAXBUF*sizeof(char));
     64     wbuf1 = (char *)malloc(MAXBUF*sizeof(char));
     65 
     66     //1.得到已连接的套接字
     67     fd = cliopen(host,port);
     68 
     69     //2.
     70     cmd_tcp(fd);
     71     
     72     exit(0);
     73 }
     74 
     75 
     76 
     77 
     78 //1.第一步,打开一个TCP链接
     79 int cliopen(char *host,int port)
     80 {
     81     int control_sock;
     82 
     83     //1.FTP 自己的传输地址结构体
     84     struct hostent *ht = NULL;
     85 
     86     //2.创建套接字
     87     control_sock = socket(AF_INET,SOCK_STREAM,0);
     88     if(control_sock < 0)
     89     {
     90        printf("socket error
    ");
     91        return -1;
     92     }
     93 
     94     //3.将IP地址进行转换,变为FTP地址结构体
     95     ht = gethostbyname(host);
     96     if(!ht)
     97     { 
     98         return -1;
     99     }
    100     
    101    //4.连接服务器,返回套接字
    102     memset(&servaddr,0,sizeof(struct sockaddr_in));
    103     memcpy(&servaddr.sin_addr.s_addr,ht->h_addr,ht->h_length);
    104     servaddr.sin_family = AF_INET;
    105     servaddr.sin_port = htons(port);
    106     
    107     if(connect(control_sock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)) == -1)
    108     {
    109         return -1;
    110     }
    111     return control_sock;
    112 }
    113 
    114 //匹配下载的文件名
    115 int s(char *str,char *s2)
    116 {
    117     //char s1[100];
    118      
    119     return sscanf(str," get %s",s2) == 1;
    120    
    121 }
    122 
    123 //匹配上传的文件名
    124 int st(char *str,char *s1)
    125 {
    126     return sscanf(str," put %s",s1) == 1;
    127 }
    128 
    129 //获取服务器 发送给 客户端的 IP地址 和 端口;
    130 int strtosrv(char *str)
    131 {
    132    int addr[6];
    133    //printf("%s
    ",str);
    134    sscanf(str,"%*[^(](%d,%d,%d,%d,%d,%d)",&addr[0],&addr[1],&addr[2],&addr[3],&addr[4],&addr[5]);
    135    bzero(host,strlen(host));
    136    sprintf(host,"%d.%d.%d.%d",addr[0],addr[1],addr[2],addr[3]);
    137    int port = addr[4]*256 + addr[5];
    138    return port;
    139 }
    140 
    141 //显示文件列表
    142 void ftp_list(int sockfd)
    143 {
    144     int nread;
    145     for(;;)
    146     {
    147         if((nread = recv(sockfd,rbuf1,MAXBUF,0)) < 0)
    148         {
    149             printf("recv error
    ");
    150         }
    151         else if(nread == 0)
    152         {
    153             //printf("over
    ");
    154             break;
    155         }
    156         if(write(STDOUT_FILENO,rbuf1,nread) != nread)
    157             printf("send error to stdout
    ");
    158         /*else
    159             printf("read something
    ");*/
    160     }
    161     if(close(sockfd) < 0)
    162         printf("close error
    ");
    163 }
    164 
    165 //下载文件
    166 int ftp_get(int sck,char *pDownloadFileName)
    167 {
    168    int handle = open(pDownloadFileName,O_WRONLY | O_CREAT | O_TRUNC, S_IREAD| S_IWRITE);
    169    int nread;
    170    printf("%d
    ",handle);
    171    /*if(handle == -1) 
    172        return -1;*/
    173 
    174     //2. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
    175    
    176    for(;;)
    177    {
    178        if((nread = recv(sck,rbuf1,MAXBUF,0)) < 0)
    179        {
    180           printf("receive error
    ");
    181        }
    182        else if(nread == 0)
    183        {
    184           printf("over
    ");
    185           break;
    186        }
    187     //   printf("%s
    ",rbuf1);
    188        if(write(handle,rbuf1,nread) != nread)
    189            printf("receive error from server!");
    190        if(write(STDOUT_FILENO,rbuf1,nread) != nread)
    191            printf("receive error from server!");
    192    }
    193        if(close(sck) < 0)
    194            printf("close error
    ");
    195 }
    196 
    197 
    198 //上传文件
    199 int ftp_put(int sck,char *pUploadFileName_s)
    200 {
    201    //int c_sock;
    202    int handle = open(pUploadFileName_s,O_RDWR);
    203    int nread;
    204    if(handle == -1)
    205        return -1;
    206    //ftp_type(c_sock,"I");
    207 
    208    //3. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
    209    for(;;)
    210    {
    211        if((nread = read(handle,rbuf1,MAXBUF)) < 0)
    212        {
    213             printf("read error!");
    214        }
    215        else if(nread == 0)
    216           break;
    217        if(write(STDOUT_FILENO,rbuf1,nread) != nread)
    218             printf("send error!");
    219        if(write(sck,rbuf1,nread) != nread)
    220             printf("send error!");
    221    }
    222    if(close(sck) < 0)
    223         printf("close error
    ");
    224 }
    225 
    226 
    227 
    228 //各种参数的执行
    229 void cmd_tcp(int sockfd)
    230 {
    231     int maxfdp1,nread,nwrite,fd,replycode,tag=0,data_sock;
    232     int port;
    233     char *pathname;
    234     fd_set rset;                //可读文件描述符集合
    235     FD_ZERO(&rset);                //清空可读文件描述符集合
    236     maxfdp1 = sockfd + 1;        //最大套接字
    237 
    238     for(;;)
    239     {
    240         //1.将  标准输入加入 可读文件描述符集合
    241          FD_SET(STDIN_FILENO,&rset);
    242         //2.将  命令套接字   加入可读文件描述符集合
    243          FD_SET(sockfd,&rset);
    244 
    245         //3.监听读事件
    246          if(select(maxfdp1,&rset,NULL,NULL,NULL)<0)
    247          {
    248              printf("select error
    ");
    249          }
    250          //4.判断标准输入是否有读事件
    251          if(FD_ISSET(STDIN_FILENO,&rset))
    252          {
    253              //5.清空读缓冲区 和 写缓冲区
    254               bzero(wbuf,MAXBUF);          //zero
    255               bzero(rbuf1,MAXBUF);
    256               
    257               if((nread = read(STDIN_FILENO,rbuf1,MAXBUF)) <0)
    258                    printf("read error from stdin
    ");
    259               nwrite = nread + 5;
    260 
    261             //=======这里不懂,replycode  什么时候赋的值
    262 
    263             //6.命令套接字中  写入  用户名
    264               if(replycode == USERNAME) 
    265               {
    266                   sprintf(wbuf,"USER %s",rbuf1);
    267               
    268                  if(write(sockfd,wbuf,nwrite) != nwrite)
    269                  {
    270                      printf("write error
    ");
    271                  }
    272                  //printf("%s
    ",wbuf);
    273                  //memset(rbuf1,0,sizeof(rbuf1));
    274                  //memset(wbuf,0,sizeof(wbuf));
    275                  //printf("1:%s
    ",wbuf);
    276               }
    277 
    278             //7.命令套接字中  写入  密码                
    279               if(replycode == PASSWORD)
    280               {
    281                    //printf("%s
    ",rbuf1);
    282                    sprintf(wbuf,"PASS %s",rbuf1);
    283                    if(write(sockfd,wbuf,nwrite) != nwrite)
    284                       printf("write error
    ");
    285                    //bzero(rbuf,sizeof(rbuf));
    286                    //printf("%s
    ",wbuf);
    287                    //printf("2:%s
    ",wbuf);
    288               }
    289               
    290               if(replycode == 550 || replycode == LOGIN || replycode == CLOSEDATA || replycode == PATHNAME || replycode == ACTIONOK)
    291               {
    292               if(strncmp(rbuf1,"pwd",3) == 0)
    293               {   
    294                      //printf("%s
    ",rbuf1);
    295                      sprintf(wbuf,"%s","PWD
    ");
    296                      write(sockfd,wbuf,4);
    297                      continue; 
    298                  }
    299                  if(strncmp(rbuf1,"quit",4) == 0)
    300                  {
    301                      sprintf(wbuf,"%s","QUIT
    ");
    302                      write(sockfd,wbuf,5);
    303                      //close(sockfd);
    304                     if(close(sockfd) <0)
    305                        printf("close error
    ");
    306                     break;
    307                  }
    308                  if(strncmp(rbuf1,"cwd",3) == 0)
    309                  {
    310                      //sprintf(wbuf,"%s","PASV
    ");
    311                      sprintf(wbuf,"%s",rbuf1);
    312                      write(sockfd,wbuf,nread);
    313                      
    314                      //sprintf(wbuf1,"%s","CWD
    ");
    315                      
    316                      continue;
    317                  }
    318                  
    319                  if(strncmp(rbuf1,"ls",2) == 0)
    320                  {
    321                      tag = 2;            //显示文件 标识符
    322                      //printf("%s
    ",rbuf1);
    323                      sprintf(wbuf,"%s","PASV
    ");
    324                      //printf("%s
    ",wbuf);
    325                      write(sockfd,wbuf,5);
    326                      //read
    327                      //sprintf(wbuf1,"%s","LIST -al
    ");
    328                      nwrite = 0;
    329                      //write(sockfd,wbuf1,nwrite);
    330                      //ftp_list(sockfd);
    331                      continue;    
    332                  }
    333                  //8.下载文件
    334                  if(strncmp(rbuf1,"get",3) == 0)
    335                  {
    336                      tag = 1;            //下载文件标识符
    337 
    338                      //被动传输模式    
    339                      sprintf(wbuf,"%s","PASV
    ");                   
    340                      //printf("%s
    ",s(rbuf1));
    341                      //char filename[100];
    342                      s(rbuf1,filename);
    343                      printf("%s
    ",filename);
    344                      write(sockfd,wbuf,5);
    345                      continue;
    346                  }
    347                  
    348                  if(strncmp(rbuf1,"put",3) == 0)
    349                  {
    350                      tag = 3;            //上传文件标识符
    351                      sprintf(wbuf,"%s","PASV
    ");
    352 
    353                     //把内容赋值给  读缓冲区
    354                      st(rbuf1,filename);
    355                      printf("%s
    ",filename);
    356                      write(sockfd,wbuf,5);
    357                      continue;
    358                  }
    359               } 
    360                     /*if(close(sockfd) <0)
    361                        printf("close error
    ");*/
    362          }
    363          if(FD_ISSET(sockfd,&rset))
    364          {
    365          //9.清空读缓冲区 和 写缓冲区
    366              bzero(rbuf,strlen(rbuf));
    367          //10.读套接字中的内容
    368              if((nread = recv(sockfd,rbuf,MAXBUF,0)) <0)
    369                   printf("recv error
    ");
    370              else if(nread == 0)
    371                break;
    372 
    373            //比较
    374              if(strncmp(rbuf,"220",3) ==0 || strncmp(rbuf,"530",3)==0)
    375              {
    376                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    377                     printf("write error to stdout
    ");*/
    378 
    379                  //链接字符串
    380                  strcat(rbuf,"your name:");
    381                 
    382                  //printf("%s
    ",rbuf);
    383                  nread += 12;
    384                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    385                     printf("write error to stdout
    ");*/
    386                  replycode = USERNAME;
    387              }
    388              if(strncmp(rbuf,"331",3) == 0)
    389              {
    390                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    391                     printf("write error to stdout
    ")*/;
    392                 strcat(rbuf,"your password:");
    393                 nread += 16;
    394                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    395                     printf("write error to stdout
    ");*/
    396                 replycode = PASSWORD;
    397              }
    398              if(strncmp(rbuf,"230",3) == 0)
    399              {
    400                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    401                     printf("write error to stdout
    ");*/
    402                 replycode = LOGIN;
    403              }
    404              if(strncmp(rbuf,"257",3) == 0)
    405              {
    406                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    407                     printf("write error to stdout
    ");*/
    408                 replycode = PATHNAME;  
    409              }
    410              if(strncmp(rbuf,"226",3) == 0)
    411              {
    412                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    413                     printf("write error to stdout
    ");*/
    414                 replycode = CLOSEDATA;
    415              }
    416              if(strncmp(rbuf,"250",3) == 0)
    417              {
    418                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    419                     printf("write error to stdout
    ");*/
    420                 replycode = ACTIONOK;
    421              }
    422              if(strncmp(rbuf,"550",3) == 0)
    423              {
    424                 replycode = 550;
    425              }
    426              /*if(strncmp(rbuf,"150",3) == 0)
    427              {
    428                 if(write(STDOUT_FILENO,rbuf,nread) != nread)
    429                     printf("write error to stdout
    ");
    430              }*/    
    431              //fprintf(stderr,"%d
    ",1);
    432              if(strncmp(rbuf,"227",3) == 0)
    433              {
    434                 //printf("%d
    ",1);
    435                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    436                    printf("write error to stdout
    ");*/
    437 
    438                 //获取服务器返回的 接收数据的端口,和地址
    439                 int port1 = strtosrv(rbuf);
    440                 printf("%d
    ",port1);
    441                 printf("%s
    ",host);
    442 
    443                 //创建新的传输数据的套接字?
    444                 //1. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
    445                 data_sock = cliopen(host,port1);
    446         
    447 
    448 
    449 //bzero(rbuf,sizeof(rbuf));
    450                 //printf("%d
    ",fd);
    451                 //if(strncmp(rbuf1,"ls",2) == 0)
    452                 if(tag == 2)
    453                 {
    454                    write(sockfd,"list
    ",strlen("list
    "));
    455                    ftp_list(data_sock);
    456                    /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
    457                        printf("write error to stdout
    ");*/
    458                    
    459                 }
    460                 //else if(strncmp(rbuf1,"get",3) == 0)
    461                 else if(tag == 1)
    462                 {
    463                     //sprintf(wbuf,"%s","RETR
    ");
    464                     //printf("%s
    ",wbuf);
    465                     //int str = strlen(filename);
    466                     //printf("%d
    ",str);
    467                     sprintf(wbuf,"RETR %s
    ",filename);
    468                     printf("%s
    ",wbuf);
    469                     //int p = 5 + str + 1;
    470 
    471                     //命令套接字中写入  下载文件命令
    472                     printf("%d
    ",write(sockfd,wbuf,strlen(wbuf)));
    473                     //printf("%d
    ",p);
    474 
    475                     //下载文件 
    476                     ftp_get(data_sock,filename);
    477                 }
    478                 else if(tag == 3)
    479                 {
    480 
    481                     // 上传文件
    482                     sprintf(wbuf,"STOR %s
    ",filename);
    483                     printf("%s
    ",wbuf);
    484                     write(sockfd,wbuf,strlen(wbuf));
    485                     ftp_put(data_sock,filename);
    486                 }
    487                 nwrite = 0;     
    488              }
    489              /*if(strncmp(rbuf,"150",3) == 0)
    490              {
    491                  if(write(STDOUT_FILENO,rbuf,nread) != nread)
    492                      printf("write error to stdout
    ");
    493              }*/
    494              //printf("%s
    ",rbuf);
    495              if(write(STDOUT_FILENO,rbuf,nread) != nread)
    496                  printf("write error to stdout
    ");
    497              /*else 
    498                  printf("%d
    ",-1);*/            
    499          }
    500     }
    501 }
  • 相关阅读:
    Spring Security(06)——AuthenticationProvider
    Spring Security(05)——异常信息本地化
    Spring Security(04)——认证简介
    Spring Security(03)——核心类简介
    Spring Security(02)——关于登录
    Spring Security(01)——初体验
    核心服务
    技术概述
    Security命名空间配置
    Spring Security
  • 原文地址:https://www.cnblogs.com/yyx1-1/p/6119245.html
Copyright © 2011-2022 走看看