程序使用
1.运行服务端 ./ftp_server 出现ftp> 
输入 get filename1.txt (filename1.txt为接收文件的名字)
2.运行客户端,如果是本机 ./fpt 127.0.0.1,出现ftp>
 输入 put filename2.txt (filename2.txt)为要发送的文件。


  1. void get_cmd(char **p)
  2. {
  3.     fgets(*p,100,stdin);
  4. }
  5. /*将带有空格的字符串s进行解析,存放到cmd字符串数组中*/

  6. int split_string(char *s,char _cmd[][100])
  7. {
  8.     char *p = s;
  9.     int i = 0;
  10.     int j = 0;
  11.     while(*p != '\n')
  12.     {
  13.         if(*p == ' ')
  14.         {    
  15.             _cmd[i][j]='\0';
  16.             i++;
  17.             j = 0;
  18.             p++;
  19.             /*处理多个空格的情况*/
  20.             while(*p == ' ')
  21.             {
  22.                 p++;
  23.             }
  24.         }
  25.         else
  26.         {
  27.             _cmd[i][j] = *p;
  28.             p++;
  29.             j++;
  30.         }        
  31.     }
  32.     return i+1;
  33. }
2.服务端ftp_server.c


  1. /*
  2.  UDP 传输方式实现FTP,服务器段
  3. */

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #include <errno.h>
  12. #include <sys/types.h>
  13. #include "cmd.h"

  14. int port = 8888;
  15. int sockfd;
  16. int bind_ret; /*绑定的返回值*/
  17. //void get_cmd(char **p);/*从控制台获取命令*/
  18. //int split_string(char *s,char _cmd[][100]); /*解析命令*/
  19. struct sockaddr_in adr_inet;/*服务器端地址信息*/
  20. void bind_ip();/*绑定服务器地址信息*/
  21. void get_file(char *_filename);/*接受文件*/
  22. int main()
  23. {
  24.     char *s; /*从控制台获得的命令*/
  25.     char (*cmd)[100];/*分割后的命令*/
  26.     int len;/*参数个数*/
  27.     s = (char *)malloc(sizeof(char)*100);
  28.         cmd = (char (*)[])malloc(sizeof(s)*10);
  29.     
  30.     bind_ip();
  31.     printf("ftp>");
  32.     get_cmd(&s);
  33.     split_string(s,cmd);

  34.     while(strcmp(cmd[0],"quit") != 0)
  35.     {
  36.         if(strcmp(cmd[0],"get") == 0)
  37.         {
  38.             char filename[100];
  39.             strcpy(filename,cmd[1]);
  40.             if(!fork())
  41.             {
  42.                 get_file(filename);
  43.                 exit(0);
  44.             }
  45.             
  46.         }        
  47.         get_cmd(&s);
  48.         len = split_string(s,cmd);

  49.     }    
  50.             
  51.     close(sockfd);
  52.     exit(0);

  53. }
  54. /*绑定服务器地址信息*/
  55. void bind_ip()
  56. {
  57.     /*建立IP地址*/
  58.     adr_inet.sin_family = AF_INET;
  59.     adr_inet.sin_port = htons(port);
  60.     adr_inet.sin_addr.s_addr = htonl(INADDR_ANY);
  61.     bzero(&(adr_inet.sin_zero),8);
  62.     /*建立socket*/
  63.     sockfd = socket(AF_INET,SOCK_DGRAM,0);
  64.     if(sockfd == -1)
  65.     {
  66.         perror("socket error!");
  67.         exit(1);
  68.     }

  69.     /*绑定socket*/    
  70.     bind_ret = bind(sockfd,(struct sockaddr *)&adr_inet,sizeof(adr_inet));
  71.     
  72.     if(bind_ret == -1)
  73.     {
  74.         perror("bind error!");
  75.         exit(1);
  76.     }
  77.     
  78. }

  79. /*接受文件*/
  80. void get_file(char *_filename)
  81. {
  82.     int len;
  83.     char buf[256];
  84.     struct sockaddr_in adr_clnt;/*用来保存客户端地址信息*/
  85.     len = sizeof(adr_clnt);
  86.     
  87.     /*创建一个文件,用来保存传送过来的文件*/
  88.     FILE *fp;
  89.     fp = fopen(_filename,"w+");
  90.     if(fp == NULL)
  91.     {
  92.         perror("create file error!");
  93.         exit(1);
  94.     }
  95.     printf("Waiting client to download!\n");
  96.     while(1)
  97.     {    
  98.         /*接受传来的信息*/
  99.         bind_ret = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_clnt,&len);
  100.         if(bind_ret < 0)
  101.         {
  102.             perror("recvfrom error!");
  103.             exit(1);
  104.         }
  105.         buf[bind_ret] = '\0';
  106.         if(strncmp(buf,"stop",4) != 0)
  107.         {        
  108.             //printf("receive :%s\n",buf);
  109.             fputs(buf,fp);
  110.         }
  111.         
  112.         if(strncmp(buf,"stop",4) == 0)
  113.         {
  114.             printf("Finished!\n");
  115.             break;
  116.         }
  117.     }
  118.     close(fp);
  119.     printf("ftp>");
  120. }
3.客户端ftp.c


  1. /*
  2.  UDP 传输方式实现FTP,客户段
  3. */

  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #include <errno.h>
  12. #include <sys/types.h>
  13. #include <unistd.h>
  14. #include <malloc.h>
  15. #include "cmd.h"

  16. int port = 8888;
  17. int sockfd;/*套接字描述符*/
  18. struct sockaddr_in adr_srvr;/*服务器地址信息*/

  19. //void get_cmd(char **p);/*从控制台获取命令*/
  20. int connect_to_server(char * ip);/*连接服务器*/
  21. //int split_string(char *s,char _cmd[][100]); /*解析命令*/
  22. void send_file(char *filename);/*发送文件*/
  23. int main(int argc,char **argv)
  24. {
  25.     
  26.     connect_to_server(argv[1]);
  27.     //connect_to_server("127.0.0.1");
  28.     char *s; /*从控制台获得的命令*/
  29.     char (*cmd)[100];/*分割后的命令*/
  30.     int len;/*输入的参数个数*/
  31.     s = (char *)malloc(sizeof(char)*100);
  32.         cmd = (char (*)[])malloc(sizeof(s)*10);
  33.     printf("ftp>");

  34.     /*注意不能用get_cmd(s),因为p存放的不是“s存放的地址”,而是
  35.      s本身的地址。详细查看“彻底搞定C指针”的第4篇。
  36.      */
  37.     get_cmd(&s);
  38.     len = split_string(s,cmd);
  39.     
  40.     while(strcmp(cmd[0],"quit") != 0)
  41.     {
  42.         if(strcmp(cmd[0],"put") == 0)
  43.         {
  44.             char filename[100];
  45.             strcpy(filename,cmd[1]);
  46.             send_file(filename);
  47.         }        
  48.         
  49.         printf("ftp>");
  50.         get_cmd(&s);
  51.         len = split_string(s,cmd);
  52.     }    
  53.     
  54.     close(sockfd);
  55.     exit(0);
  56.         
  57. }
  58. int connect_to_server(char * ip)
  59. {
  60.     struct hostent *host;
  61.     printf("Connect to server……\n");
  62.     /*建立IP地址*/
  63.     host = gethostbyname(ip);
  64.     if(host == NULL)
  65.     {
  66.         herror("gethostbyname error!");
  67.         exit(1);
  68.     }

  69.     /*初始化服务器地址信息*/
  70.     adr_srvr.sin_family = AF_INET;
  71.     adr_srvr.sin_port = htons(port);
  72.     adr_srvr.sin_addr = *((struct in_addr *)host->h_addr);
  73.     bzero(&(adr_srvr.sin_zero),8);
  74.     
  75.     /*建立socket*/
  76.     sockfd = socket(AF_INET,SOCK_DGRAM,0);
  77.     if(sockfd == -1)
  78.     {
  79.         perror("socket error!");
  80.         exit(1);
  81.     }
  82.     return 1;
  83. }

  84. void send_file(char *_filename)
  85. {
  86.     FILE *fp;
  87.     int send_ret;
  88.     char buf[256];
  89.     char str1[80];
  90.     fp = fopen(_filename,"r");
  91.     if(fp == NULL)
  92.     {
  93.         perror("open failed!");
  94.         return ;
  95.     }
  96.     //读取数据传递给UDPserver
  97.     printf("Sending……\n");
  98.     while(fgets(str1,256,fp)!=NULL)
  99.     {
  100.      //printf("%s\n",str1);
  101.         sprintf(buf,"%s",str1);
  102.         
  103.         send_ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_srvr,sizeof(adr_srvr));
  104.         
  105.         if(send_ret < 0)
  106.         {
  107.             perror("sendto error!");
  108.             return;
  109.         }
  110.     }
  111.     printf("Finished!\n");    
  112.     sprintf(buf,"stop\n");
  113.     
  114.     send_ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&adr_srvr,sizeof(adr_srvr));
  115.     
  116.     if(send_ret < 0)
  117.     {
  118.         perror("sendto error!");
  119.         return ;
  120.     }
  121.     fclose(fp);
  122. }













10-02 08:33