zoukankan      html  css  js  c++  java
  • Socket网络编程--小小网盘程序(5)

      各位好呀!这一小节应该就是这个小小网盘程序的最后一小节了,这一节将实现最后的三个功能,即列出用户在服务器中的文件列表,还有删除用户在服务器中的文件,最后的可以共享文件给好友。

      列出用户在服务器中的文件列表

      增加一个结构体

    1 struct FileList
    2 {
    3     int cnt;
    4     char list[16][128];
    5 };

      为了方便我就假设服务器最多可以存16个单个用户的文件。如果想要支持更多的文件,这里可以增加一个int pages;用于分页作用,我们在服务器中获取文件时,可以根据分页进行发送。这样既方便又能支持多文件。

      client.cpp这个客户端文件增加一个函数

     1 int file_list(struct Addr addr,struct User user)
     2 {
     3     struct sockaddr_in servAddr;
     4     struct hostent *host;
     5     struct Control control;
     6     struct FileList filelist;
     7     int sockfd;
     8 
     9     host=gethostbyname(addr.host);
    10     servAddr.sin_family=AF_INET;
    11     servAddr.sin_addr=*((struct in_addr *)host->h_addr);
    12     servAddr.sin_port=htons(addr.port);
    13     if(host==NULL)
    14     {
    15         perror("获取IP地址失败");
    16         exit(-1);
    17     }
    18     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    19     {
    20         perror("socket创建失败");
    21         exit(-1);
    22     }
    23     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)
    24     {
    25         perror("connect 失败");
    26         exit(-1);
    27     }
    28 
    29     //控制信号
    30     control.control=FILE_LIST;
    31     control.uid=user.uid;
    32     if(send(sockfd,(char *)&control,sizeof(struct Control),0)<0)
    33     {
    34         perror("文件指纹发送失败");
    35         exit(-1);
    36     }
    37     if(recv(sockfd,(char *)&filelist,sizeof(struct FileList),0)<0)
    38     {
    39         perror("获取文件列表失败");
    40         exit(-1);
    41     }
    42     for(int i=0;i<filelist.cnt;i++)
    43     {
    44         printf("--> %s
    ",filelist.list[i]);
    45     }
    46 
    47     close(sockfd);
    48     return 0;
    49 }

      然后在主函数中调用即可。

      server.cpp实现,在主函数的case FILE_LIST:处修改如下

    1  case FILE_LIST:
    2  {
    3       struct File file;
    4       struct FileList filelist;
    5       file.uid=control.uid;
    6       mysql_get_file_list(file,&filelist);
    7       send(clientfd,(char *)&filelist,sizeof(struct FileList),0);
    8       break;
    9   }

      然后再增加一个对应的mysql_get_file_list函数

     1 int mysql_get_file_list(struct File file,struct FileList *filelist)
     2 {
     3     MYSQL conn;
     4     MYSQL_RES * res_ptr;
     5     MYSQL_ROW result_row;
     6     int res;int row;int column;
     7     int i,j;
     8     char sql[256]={0};
     9     char ch[64];
    10     //select filename from files,relations where relations.uid=[file].uid and relations.fid=files.fid;
    11     strcpy(sql,"select filename from files,relations where relations.uid=");
    12     sprintf(ch,"%d",file.uid);
    13     strcat(sql,ch);
    14     strcat(sql," and relations.fid=files.fid ;");
    15     //printf("==>%s
    ",sql);
    16 
    17     mysql_init(&conn);
    18     if(mysql_real_connect(&conn,"localhost","root","","filetranslate",0,NULL,CLIENT_FOUND_ROWS))
    19     {
    20         res=mysql_query(&conn,sql);
    21         if(res)
    22         {
    23             perror("select sql error1");
    24         }
    25         else
    26         {
    27             res_ptr=mysql_store_result(&conn);
    28             if(res_ptr)
    29             {
    30                 column=mysql_num_fields(res_ptr);
    31                 row=mysql_num_rows(res_ptr)+1;
    32                 //按行输出结果
    33                 filelist->cnt=row-1;
    34                 for(i=1;i<row;i++)
    35                 {
    36                     result_row=mysql_fetch_row(res_ptr);
    37                     strcpy(filelist->list[i-1],result_row[0]);
    38                     //printf("%s",result_row[0]);
    39                 }
    40             }
    41             else
    42             {
    43                 printf("没有数据
    ");
    44             }
    45         }
    46     }
    47     else
    48     {
    49         perror("Connect Failed1
    ");
    50         exit(-1);
    51     }
    52     mysql_close(&conn);
    53     return 0;
    54 }

      运行时的截图

      删除服务器中的用户文件

      在client.cpp中增加一个file_delete函数

     1 int file_delect(struct Addr addr,struct User user,char *filenames)
     2 {
     3     struct sockaddr_in servAddr;
     4     struct hostent *host;
     5     struct Control control;
     6     struct File file;
     7     int sockfd;
     8 
     9     host=gethostbyname(addr.host);
    10     servAddr.sin_family=AF_INET;
    11     servAddr.sin_addr=*((struct in_addr *)host->h_addr);
    12     servAddr.sin_port=htons(addr.port);
    13     if(host==NULL)
    14     {
    15         perror("获取IP地址失败");
    16         exit(-1);
    17     }
    18     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    19     {
    20         perror("socket创建失败");
    21         exit(-1);
    22     }
    23     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)
    24     {
    25         perror("connect 失败");
    26         exit(-1);
    27     }
    28 
    29     //控制信号
    30     control.control=FILE_DELECT;
    31     control.uid=user.uid;
    32     if(send(sockfd,(char *)&control,sizeof(struct Control),0)<0)
    33     {
    34         perror("文件指纹发送失败");
    35         exit(-1);
    36     }
    37     file.uid=user.uid;
    38     strcpy(file.filename,filenames);
    39     if(send(sockfd,(char *)&file,sizeof(struct File),0)<0)
    40     {
    41         perror("删除文件失败");
    42         exit(-1);
    43     }
    44     char ch[32];
    45     memset(ch,0,sizeof(ch));
    46     if(recv(sockfd,ch,sizeof(ch),0)<0)
    47     {
    48         perror("删除文件失败");
    49         exit(-1);
    50     }
    51     if(ch[0]=='y') //删除成功
    52     {
    53         printf("删除成功
    ");;
    54     }
    55     else if(ch[0]=='n') //删除失败
    56     {
    57         printf("删除失败,确认是否有该文件
    ");;
    58     }
    59     close(sockfd);
    60     return 0;
    61 }

      在server.cpp的main函数中增加

     1 case FILE_DELECT:
     2 {
     3     struct File file;
     4     char ch[64];
     5     memset(ch,0,sizeof(ch));
     6     recv(clientfd,(char *)&file,sizeof(struct File),0);
     7     int t=mysql_delete_file(file);
     8     if(t==-1)
     9     {
    10          printf("没有对应的文件
    ");;
    11          strcpy(ch,"no");
    12          send(clientfd,ch,64,0);
    13          break;
    14      }
    15       strcpy(ch,"yes");
    16       send(clientfd,ch,64,0);
    17       printf("删除成功
    ");
    18       break;
    19 }

      然后在server.cpp中再增加一个mysql_delete_file函数

     1 int mysql_delete_file(struct File file)
     2 {
     3     MYSQL conn;
     4     MYSQL_RES * res_ptr;
     5     MYSQL_ROW result_row;
     6     int res;int row;int column;
     7     int i,j;
     8     char sql[256];
     9     char ch[64];
    10     int fid;int rt=0;
    11 
    12     mysql_init(&conn);
    13     if(mysql_real_connect(&conn,"localhost","root","","filetranslate",0,NULL,CLIENT_FOUND_ROWS))
    14     {
    15         //select files.fid from files,relations where relations.fid=files.fid and filename= [file].filename
    16         strcpy(sql,"select files.fid from files,relations where relations.fid=files.fid and filename="");
    17         strcat(sql,file.filename);
    18         strcat(sql,"";");
    19         res=mysql_query(&conn,sql);
    20         fid=0;
    21         if(res)
    22         {
    23             perror("Select Sql Error!");
    24         }
    25         else
    26         {
    27             res_ptr=mysql_store_result(&conn);
    28             if(res_ptr)
    29             {
    30                 column=mysql_num_fields(res_ptr);
    31                 row=mysql_num_rows(res_ptr)+1;
    32                 if(row<=1)
    33                     ;
    34                 else
    35                 {
    36                     result_row=mysql_fetch_row(res_ptr);
    37                     if(result_row[0]==NULL)
    38                     {
    39                         fid=0;
    40                     }
    41                     else
    42                     {
    43                         fid=atoi(result_row[0]);
    44                     }
    45                 }
    46             }
    47             else
    48             {
    49                 fid=0;
    50             }
    51         }
    52         if(fid==0)
    53         {
    54             mysql_close(&conn);
    55             return -1;
    56         }
    57         //根据获取到的fid然后删除relations对应fid和uid
    58         //delect relations where uid='uid' and fid='fid'
    59         strcpy(sql,"delete from relations where uid=");
    60         sprintf(ch,"%d",file.uid);
    61         strcat(sql,ch);
    62         strcat(sql," and fid=");
    63         sprintf(ch,"%d",fid);
    64         strcat(sql,ch);
    65         res=mysql_query(&conn,sql);
    66         if(res)
    67         {
    68             printf("Delete Error
    ");
    69         }
    70         else
    71         {
    72             ;;
    73         }
    74     }
    75     else
    76     {
    77         perror("Connect Failed!");
    78         exit(-1);
    79     }
    80 
    81     mysql_close(&conn);
    82     return rt;
    83 }

      从上面的sql语句可以知道我们只是删除了relations表中的链接而已。而没有真正的删除已经上传上去的文件。这一点可以参考以前给过的资料。

      运行的截图如下

      文件共享给好友

      client.cpp文件加入一个函数

     1 int file_sendto(struct Addr addr,struct User user,char *filenames,struct User to)
     2 {
     3     struct sockaddr_in servAddr;
     4     struct hostent *host;
     5     struct Control control;
     6     struct File file;
     7     int sockfd;
     8 
     9     host=gethostbyname(addr.host);
    10     servAddr.sin_family=AF_INET;
    11     servAddr.sin_addr=*((struct in_addr *)host->h_addr);
    12     servAddr.sin_port=htons(addr.port);
    13     if(host==NULL)
    14     {
    15         perror("获取IP地址失败");
    16         exit(-1);
    17     }
    18     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    19     {
    20         perror("socket创建失败");
    21         exit(-1);
    22     }
    23     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)
    24     {
    25         perror("connect 失败");
    26         exit(-1);
    27     }
    28 
    29     //控制信号
    30     control.control=FILE_SENDTO;
    31     control.uid=user.uid;
    32     if(send(sockfd,(char *)&control,sizeof(struct Control),0)<0)
    33     {
    34         perror("文件指纹发送失败");
    35         exit(-1);
    36     }
    37     file.uid=user.uid;
    38     strcpy(file.filename,filenames);
    39     if(send(sockfd,(char *)&file,sizeof(struct File),0)<0)
    40     {
    41         perror("共享文件失败");
    42         exit(-1);
    43     }
    44     if(send(sockfd,(char *)&to,sizeof(struct User),0)<0)
    45     {
    46         perror("共享用户发送失败");
    47         exit(-1);
    48     }
    49     char ch[32];
    50     memset(ch,0,sizeof(ch));
    51     if(recv(sockfd,ch,sizeof(ch),0)<0)
    52     {
    53         perror("共享文件失败");
    54         exit(-1);
    55     }
    56     if(ch[0]=='y') //删除成功
    57     {
    58         printf("共享成功
    ");;
    59     }
    60     else if(ch[0]=='n') //删除失败
    61     {
    62         if(ch[2]=='1')
    63             printf("共享失败,确认是否有该文件
    ");
    64         else if(ch[2]=='2')
    65             printf("共享失败,确认是否有该用户
    ");
    66     }
    67     close(sockfd);
    68     return 0;
    69 }

      而server.cpp在主函数main中switch中增加如下

     1 case FILE_SENDTO:
     2 {
     3      struct File file;
     4      struct User to;
     5      recv(clientfd,(char *)&file,sizeof(struct File),0);
     6      recv(clientfd,(char *)&to,sizeof(struct User),0);
     7      int t=mysql_sendto(file,to);
     8      char ch[64];
     9      memset(ch,0,sizeof(ch));
    10      if(t==-1)
    11      {
    12           printf("没有对应的文件
    ");;
    13           strcpy(ch,"no1");
    14           send(clientfd,ch,64,0);
    15           break;
    16      }
    17      else if(t==-2)
    18      {
    19           printf("没有对应的用户
    ");;
    20           strcpy(ch,"no2");
    21           send(clientfd,ch,64,0);
    22           break;
    23      }
    24           strcpy(ch,"yes");
    25           send(clientfd,ch,64,0);
    26           printf("共享成功
    ");
    27           break;
    28 }

      然后对应的增加下面一个函数

      1 int mysql_sendto(struct File file,struct User to)
      2 {
      3     //insert into relations values(uid,fid);
      4     MYSQL conn;
      5     MYSQL_RES * res_ptr;
      6     MYSQL_ROW result_row;
      7     int res;int row;int column;
      8     int i,j;int fid;int uid;int rt=0;
      9     char sql[256];
     10     char ch[64];
     11 
     12     mysql_init(&conn);
     13     if(mysql_real_connect(&conn,"localhost","root","","filetranslate",0,NULL,CLIENT_FOUND_ROWS))
     14     {
     15         //select files.fid from files,relations where relations.fid=files.fid and filename=files.filename;
     16         //得到fid后
     17         strcpy(sql,"select files.fid from files,relations where relations.fid=files.fid and filename="");
     18         strcat(sql,file.filename);
     19         strcat(sql,"";");
     20         res=mysql_query(&conn,sql);
     21         fid=0;
     22         if(res)
     23         {
     24             perror("Select Sql Error!");
     25         }
     26         else
     27         {
     28             res_ptr=mysql_store_result(&conn);
     29             if(res_ptr)
     30             {
     31                 column=mysql_num_fields(res_ptr);
     32                 row=mysql_num_rows(res_ptr)+1;
     33                 if(row<=1)
     34                     ;
     35                 else
     36                 {
     37                     result_row=mysql_fetch_row(res_ptr);
     38                     if(result_row[0]==NULL)
     39                     {
     40                         fid=0;
     41                     }
     42                     else
     43                     {
     44                         fid=atoi(result_row[0]);
     45                     }
     46                 }
     47             }
     48             else
     49             {
     50                 fid=0;
     51             }
     52         }
     53         if(fid==0)
     54         {
     55             mysql_close(&conn);
     56             return -1;//表示没有该文件
     57         }
     58 
     59         //select uid from users where username=[to].username;
     60         //得到uid后
     61         strcpy(sql,"select uid from users where username="");
     62         strcat(sql,to.username);
     63         strcat(sql,""");
     64         res=mysql_query(&conn,sql);
     65         uid=0;
     66         if(res)
     67         {
     68             perror("Select Sql Error!");
     69         }
     70         else
     71         {
     72             res_ptr=mysql_store_result(&conn);
     73             if(res_ptr)
     74             {
     75                 column=mysql_num_fields(res_ptr);
     76                 row=mysql_num_rows(res_ptr)+1;
     77                 if(row<=1)
     78                     ;
     79                 else
     80                 {
     81                     result_row=mysql_fetch_row(res_ptr);
     82                     if(result_row[0]==NULL)
     83                     {
     84                         uid=0;
     85                     }
     86                     else
     87                     {
     88                         uid=atoi(result_row[0]);
     89                     }
     90                 }
     91             }
     92             else
     93             {
     94                 uid=0;
     95             }
     96         }
     97         if(uid==0)
     98         {
     99             mysql_close(&conn);
    100             return -2;//表示没有该用户
    101         }
    102 
    103         //将获取到的uid fid插入到数据库relations中
    104         //insert into relations values(uid,fid);
    105         strcpy(sql,"insert into relations values( ");
    106         sprintf(ch,"%d",uid);
    107         strcat(sql,ch);
    108         strcat(sql,", ");
    109         sprintf(ch,"%d",fid);
    110         strcat(sql,ch);
    111         strcat(sql,");");
    112         res=mysql_query(&conn,sql);
    113         printf("==========> uid=%d  fid=%d
    ",uid,fid);
    114         if(res)
    115         {
    116             rt=-1;
    117             printf("Insert Error
    ");
    118         }
    119         else
    120         {
    121             printf("Insert Success
    ");
    122         }
    123     }
    124     else
    125     {
    126         perror("Connect Failed!");
    127         exit(-1);
    128     }
    129     mysql_close(&conn);
    130     return rt;
    131 }

      下面这个是运行时的截图

      在本次程序的最后,送上程序代码结构,及本人的开发环境。

      从程序中可以看出很多代码是有冗余的,如果进行重构的话,估计代码可以节省50%。可怕的新手啊(◑﹏◐)。从代码量上看,这次的代码量也不少了,相比与上次聊天程序,代码量有过之而不及,不过可喜的是这次都把具体的功能封装成一个一个的函数,即使有冗余代码。不过还是有点小进步了。

      Socket网络编程--小小网盘程序各个小节的传送门

      Socket网络编程--小小网盘程序(1) http://www.cnblogs.com/wunaozai/p/3886588.html
      Socket网络编程--小小网盘程序(2) http://www.cnblogs.com/wunaozai/p/3887728.html
      Socket网络编程--小小网盘程序(3) http://www.cnblogs.com/wunaozai/p/3891062.html
      Socket网络编程--小小网盘程序(4) http://www.cnblogs.com/wunaozai/p/3892729.html
      Socket网络编程--小小网盘程序(5) http://www.cnblogs.com/wunaozai/p/3893469.html

      本文地址: http://www.cnblogs.com/wunaozai/p/3893469.html 

      代码下载: http://files.cnblogs.com/wunaozai/xiaoxiaowangpan.zip

  • 相关阅读:
    python笔记005-字符串-列表-元组
    Python笔记2 标准数据类型
    VS2010与VAssistX
    【Windows核心编程】Windows常见数据类型
    网络安全加密
    防御 XSS 的七条原则
    用户权限初略设计
    [Android]Handler的消息机制
    java的线程中的Runnable
    [转]永久告别Android的背景选择器Selector!无需切很多图了!
  • 原文地址:https://www.cnblogs.com/wunaozai/p/3893469.html
Copyright © 2011-2022 走看看