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\n",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\n",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("没有数据\n");
44             }
45         }
46     }
47     else
48     {
49         perror("Connect Failed1\n");
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("删除成功\n");;
54     }
55     else if(ch[0]=='n') //删除失败
56     {
57         printf("删除失败,确认是否有该文件\n");;
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("没有对应的文件\n");;
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("删除成功\n");
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\n");
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("共享成功\n");;
59     }
60     else if(ch[0]=='n') //删除失败
61     {
62         if(ch[2]=='1')
63             printf("共享失败,确认是否有该文件\n");
64         else if(ch[2]=='2')
65             printf("共享失败,确认是否有该用户\n");
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("没有对应的文件\n");;
13           strcpy(ch,"no1");
14           send(clientfd,ch,64,0);
15           break;
16      }
17      else if(t==-2)
18      {
19           printf("没有对应的用户\n");;
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("共享成功\n");
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\n",uid,fid);
114         if(res)
115         {
116             rt=-1;
117             printf("Insert Error\n");
118         }
119         else
120         {
121             printf("Insert Success\n");
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 

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

posted @ 2014-08-06 09:17  无脑仔的小明  阅读(2133)  评论(4编辑  收藏  举报