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\n","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\n");
 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\n",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\n");
150         }
151         else if(nread == 0)
152         {
153             //printf("over\n");
154             break;
155         }
156         if(write(STDOUT_FILENO,rbuf1,nread) != nread)
157             printf("send error to stdout\n");
158         /*else
159             printf("read something\n");*/
160     }
161     if(close(sockfd) < 0)
162         printf("close error\n");
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\n",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\n");
181        }
182        else if(nread == 0)
183        {
184           printf("over\n");
185           break;
186        }
187     //   printf("%s\n",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\n");
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\n");
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\n");
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\n");
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\n");
271                  }
272                  //printf("%s\n",wbuf);
273                  //memset(rbuf1,0,sizeof(rbuf1));
274                  //memset(wbuf,0,sizeof(wbuf));
275                  //printf("1:%s\n",wbuf);
276               }
277 
278             //7.命令套接字中  写入  密码                
279               if(replycode == PASSWORD)
280               {
281                    //printf("%s\n",rbuf1);
282                    sprintf(wbuf,"PASS %s",rbuf1);
283                    if(write(sockfd,wbuf,nwrite) != nwrite)
284                       printf("write error\n");
285                    //bzero(rbuf,sizeof(rbuf));
286                    //printf("%s\n",wbuf);
287                    //printf("2:%s\n",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\n",rbuf1);
295                      sprintf(wbuf,"%s","PWD\n");
296                      write(sockfd,wbuf,4);
297                      continue; 
298                  }
299                  if(strncmp(rbuf1,"quit",4) == 0)
300                  {
301                      sprintf(wbuf,"%s","QUIT\n");
302                      write(sockfd,wbuf,5);
303                      //close(sockfd);
304                     if(close(sockfd) <0)
305                        printf("close error\n");
306                     break;
307                  }
308                  if(strncmp(rbuf1,"cwd",3) == 0)
309                  {
310                      //sprintf(wbuf,"%s","PASV\n");
311                      sprintf(wbuf,"%s",rbuf1);
312                      write(sockfd,wbuf,nread);
313                      
314                      //sprintf(wbuf1,"%s","CWD\n");
315                      
316                      continue;
317                  }
318                  
319                  if(strncmp(rbuf1,"ls",2) == 0)
320                  {
321                      tag = 2;            //显示文件 标识符
322                      //printf("%s\n",rbuf1);
323                      sprintf(wbuf,"%s","PASV\n");
324                      //printf("%s\n",wbuf);
325                      write(sockfd,wbuf,5);
326                      //read
327                      //sprintf(wbuf1,"%s","LIST -al\n");
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\n");                   
340                      //printf("%s\n",s(rbuf1));
341                      //char filename[100];
342                      s(rbuf1,filename);
343                      printf("%s\n",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\n");
352 
353                     //把内容赋值给  读缓冲区
354                      st(rbuf1,filename);
355                      printf("%s\n",filename);
356                      write(sockfd,wbuf,5);
357                      continue;
358                  }
359               } 
360                     /*if(close(sockfd) <0)
361                        printf("close error\n");*/
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\n");
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\n");*/
378 
379                  //链接字符串
380                  strcat(rbuf,"your name:");
381                 
382                  //printf("%s\n",rbuf);
383                  nread += 12;
384                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
385                     printf("write error to stdout\n");*/
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\n")*/;
392                 strcat(rbuf,"your password:");
393                 nread += 16;
394                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
395                     printf("write error to stdout\n");*/
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\n");*/
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\n");*/
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\n");*/
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\n");*/
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\n");
430              }*/    
431              //fprintf(stderr,"%d\n",1);
432              if(strncmp(rbuf,"227",3) == 0)
433              {
434                 //printf("%d\n",1);
435                 /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
436                    printf("write error to stdout\n");*/
437 
438                 //获取服务器返回的 接收数据的端口,和地址
439                 int port1 = strtosrv(rbuf);
440                 printf("%d\n",port1);
441                 printf("%s\n",host);
442 
443                 //创建新的传输数据的套接字?
444                 //1. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
445                 data_sock = cliopen(host,port1);
446         
447 
448 
449 //bzero(rbuf,sizeof(rbuf));
450                 //printf("%d\n",fd);
451                 //if(strncmp(rbuf1,"ls",2) == 0)
452                 if(tag == 2)
453                 {
454                    write(sockfd,"list\n",strlen("list\n"));
455                    ftp_list(data_sock);
456                    /*if(write(STDOUT_FILENO,rbuf,nread) != nread)
457                        printf("write error to stdout\n");*/
458                    
459                 }
460                 //else if(strncmp(rbuf1,"get",3) == 0)
461                 else if(tag == 1)
462                 {
463                     //sprintf(wbuf,"%s","RETR\n");
464                     //printf("%s\n",wbuf);
465                     //int str = strlen(filename);
466                     //printf("%d\n",str);
467                     sprintf(wbuf,"RETR %s\n",filename);
468                     printf("%s\n",wbuf);
469                     //int p = 5 + str + 1;
470 
471                     //命令套接字中写入  下载文件命令
472                     printf("%d\n",write(sockfd,wbuf,strlen(wbuf)));
473                     //printf("%d\n",p);
474 
475                     //下载文件 
476                     ftp_get(data_sock,filename);
477                 }
478                 else if(tag == 3)
479                 {
480 
481                     // 上传文件
482                     sprintf(wbuf,"STOR %s\n",filename);
483                     printf("%s\n",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\n");
493              }*/
494              //printf("%s\n",rbuf);
495              if(write(STDOUT_FILENO,rbuf,nread) != nread)
496                  printf("write error to stdout\n");
497              /*else 
498                  printf("%d\n",-1);*/            
499          }
500     }
501 }

 

转载于:https://www.cnblogs.com/yyx1-1/p/6119245.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
 FTP(File Transfer Protocol),是文件传输协议的简称。用于Internet上的控制文件的双向传输。本程序采用Java编写ftp 命令使用“文件传送协议” (FTP) 在本地和远程主机或远程主机之间传送文件。   FTP 协议允许在使用不同文件系统的主机之间进行数据传送。尽管协议在传送数据中提供了很高的灵活度,它仍然不会尝试保留特定于某个文件系统的文件属性(如文件保护模式或修改时间)。而且,FTP 协议为文件系统的整体结构做了少许假设,且不提供或不允许诸如循环地复制子目录这样的函数。   请注意:如果您正在系统之间传送文件,且需要保存文件属性或递归地复制子目录,请使用 rcp 命令。 您可以在 ftp> 提示符中输入子命令,执行类似这样的任务:列出远程目录、更改当前的本地和远程目录、在单一请求中传送多个文件、创建和除去目录,以及转义到本地 shell 执行 shell 命令。请参考子命令章节取得每个子命令的描述信息。   如果您执行 ftp 命令而不为远程主机指定 HostName 参数,ftp 命令会立即显示 ftp> 提示符,等待 ftp 子命令。要连接远程主机,请执行 open 子命令。 当 ftp 命令连接到远程主机时,ftp 命令在再次显示提示符 ftp> 之前会提示输入登录名和密码。如果远程主机中未定义登录名的密码,ftp 命令将不成功。   ftp 命令解释器(处理在 ftp> 提示符处输入的全部子命令),会提供大多数文件传送程序没有的性能,如:   * 对 ftp 子命令处理文件名参数   * 将一组子命令集中成一个单一的子命令宏   * 从 $HOME/.netrc 文件中装入宏   这些性能会帮助您简化重复的任务,并允许您在 unattended 方式使用 ftp 命令。   命令解释器将按照下列规则处理文件名参数:   * 如果为此参数指定了 -(连字符),则标准输入 (stdin) 将用于读取操作,而标准输出用于写入操作。   * 如果未应用前面的检查,且文件名扩展已启用(请参考 -g 标志或 glob 子命令),则解释器将根据 C shell 的规则扩展文件名。启用了文件名匹配替换以及在期待单一文件名的子命令中使用了模式匹配字符时,结果可能与期待的不一样。   例如,append 和 put 子命令将拓展文件名,然后仅使用所生成第一个文件名。其它 ftp 子命令,如 cd、delete, get、mkdir、rename 和 rmdir 不会执行文件名拓展,并从字面上接受模式匹配字符。  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值