Chinaunix首页 | 论坛 | 博客
  • 博客访问: 338458
  • 博文数量: 45
  • 博客积分: 669
  • 博客等级: 上士
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-27 17:59
文章分类
文章存档

2015年(5)

2014年(6)

2013年(4)

2012年(30)

分类: LINUX

2012-07-25 09:02:53

本套系统功能简介:服务器登陆后,自动扫描指定目录中的指定文件(本文中指定为MP3文件),打印出服务器中的文件及数目,然后等待客户端的连接,一旦有客户端连接,服务器将扫描出的全部同类型文件发送给客户端,实现文件同步。可应用于广播等应用中。

设计思路:服务器先扫描指定类型的文件,将扫描结果存于链表中。然后建立套接字,等待客户端连接,等有客户端连接后,依次发送文件数目,文件名,文件大小及文件内容给客户端。客户端依次接收。

设计难点在于客户端的文件内容的接收,需要文件大小控制文件内容接收循环的跳出,否则会接收下个文件的内容,造成文件接收混乱。

server 端:

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/socket.h>                            // 包含套接字函数库
  3. #include <stdio.h>
  4. #include <netinet/in.h>                            // 包含AF_INET相关结构
  5. #include <arpa/inet.h>                        // 包含AF_INET相关操作的函数
  6. #include <unistd.h>
  7. #include<string.h>
  8. #include<stdlib.h>
  9. #include<fcntl.h>
  10. #include<sys/stat.h>
  11. #include<dirent.h>

  12. #define PORT 9999
  13. #define BUFFSIZE 1000



  14. #define MAXPATH 32
  15. #define LEN sizeof(struct list)

  16. int count=0;            //计量歌曲数
  17. double filesize; //文件总大小

  18. struct list
  19. {
  20.     char pathname[1024];
  21.     char filename[512];
  22.     struct list *next;
  23. };

  24.  struct list *head,*p1,*p2;


  25. void scan_dir(char *dir,int depth)         //定义目录扫描函数
  26. {
  27.     DIR *dp;
  28.     struct dirent *entry;
  29.     struct stat statbuff;
  30.     int l;
  31.     if(!(dp=opendir(dir)))
  32.     {
  33.         //puts(\"can\'t open\");
  34.         return;
  35.     }

  36.     chdir(dir);                //切换到当前目录中去
  37.     while((entry=readdir(dp))!=NULL)
  38.     {
  39.         lstat(entry->d_name,&statbuff);    //获取下一级成员属性
  40.         if(S_IFDIR&statbuff.st_mode)    //判断下一级成员是否是目录
  41.         {
  42.             if(strcmp(\".\",entry->d_name)==0||
  43.                 strcmp(\"..\",entry->d_name)==0)
  44.             continue;
  45.             
  46.             //printf(\"%*s%s/\\n\",depth,\"\",entry->d_name);
  47.             scan_dir(entry->d_name,depth+4);    //调用自身,扫描下一级
  48.         
  49.         }

  50.         else
  51.              {
  52.                 l=strlen(entry->d_name);
  53.          l-=4;
  54.          if(strcmp(entry->d_name+l,\".mp3\")==0||
  55.                         strcmp(entry->d_name+l,\".MP3\")==0)
  56.                 {    char path_buff[MAXPATH];
  57.                     getcwd(path_buff, MAXPATH);

  58.                     
  59.                     p1= malloc(LEN);

  60.                     strcpy(p1->pathname,path_buff);
  61.                     strcpy(p1->filename,entry->d_name);
  62.                     
  63.                 //printf(\"%s hello %s\",p1->pathname,p1->filename);
  64.                     p1->next=0;
  65.                     count++;
  66.                     
  67.                     if(count==1)
  68.                         head=p2=p1;
  69.                     else
  70.                     {    p2->next=p1;
  71.                         //p2=p2->next;
  72.                         p2=p1;
  73.                         //printf(\"hello\");
  74.                         
  75.                     }
  76.                     
  77.                 
  78.                     
  79.                     int tem;
  80.                         tem = statbuff.st_size;
  81.                         
  82.                      filesize+=tem;
  83.                 
  84.                 }
  85.                 
  86.             }

  87.     }

  88.     chdir(\"..\");                //回到上一级目录
  89.     closedir(dp);

  90. }


  91. int print()
  92. {
  93.     
  94.     struct list *temp;
  95.     temp=head;
  96.     //printf(\"......here1\");
  97.     if(head!=NULL)
  98.         do {
  99.             printf(\"%s %s\\n\",temp->pathname,temp->filename);
  100.             
  101.             temp=temp->next;    
  102.          }while(temp!=NULL);
  103.         return ;
  104. }





  105. int main()
  106. {
  107.     
  108.     puts(\"正在扫描全盘中...\");    
  109.     scan_dir(\"/home\",0);
  110.     printf(\"列表输出如下:\\n\");
  111.     
  112.     print();
  113.     puts(\"扫描结束\\n\");
  114.     printf(\"共计%d首歌曲\\n\",count);
  115.     printf(\"总大小为%3.2gMB\\n\",filesize/1024/1024);

  116.     
  117.    



  118.     /* 以下为socket创建过程 */
  119.     int server_sockfd,client_sockfd;
  120.     int server_len,client_len;
  121.     
  122.     struct sockaddr_in server_sockaddr,client_sockaddr;
  123.     
  124.     server_sockfd = socket(AF_INET,SOCK_STREAM, 0);    // 定义套接字类型
  125.     
  126.     server_sockaddr.sin_family=AF_INET;
  127.     server_sockaddr.sin_port=htons(PORT);
  128.     server_sockaddr.sin_addr.s_addr=INADDR_ANY;
  129.     
  130.     server_len=sizeof(server_sockaddr);
  131.     
  132.     //允许重复使用本地地址和套接字绑定
  133.     int j=1;
  134.     setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,&j,sizeof(j));
  135.     
  136.     //绑定端口
  137.     if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,server_len)==-1)
  138.     {
  139.         perror(\"bind:\");
  140.         exit(1);
  141.     }
  142.      
  143.     //监听端口
  144.     if(listen(server_sockfd,5)==-1)
  145.     {
  146.         perror(\"listen:\");
  147.         exit(1);
  148.     }
  149.     printf(\"Listening...\\n\");
  150.     
  151.    pid_t pid;
  152.     
  153.    client_len=sizeof(client_sockaddr);
  154.    while(1)
  155.    {
  156.     if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_sockaddr,&client_len))==-1)
  157.         {
  158.              perror(\"accept error:\");
  159.              exit(1);
  160.         }

  161.     printf(\"%s连接到服务器\\n\",inet_ntoa(client_sockaddr.sin_addr));
  162.     
  163.     printf(\"准备发送文件...\\n\");
  164.     
  165.     pid=fork(); //创建子进程
  166.    
  167.    if(pid==0) //子进程发送数据
  168.    {
  169.     //发送文件数目
  170.     int countbyte;
  171.     countbyte=send(client_sockfd,&count,4,0);
  172.    // printf(\"countbyte=%d\\n\",countbyte);
  173.     
  174.     
  175.     
  176.     
  177.     
  178.     char fileinfo[100]; //定义文件信息,包括文件路径和文件名
  179.     memset(fileinfo,0,100);
  180.     char filename[50];
  181.     memset(filename,0,50);
  182.     
  183.    
  184.     
  185.     struct stat statbuff;
  186.     struct list *temp;
  187.     temp=head;
  188.     
  189.     
  190.     

  191.     if(head!=NULL)
  192.         do {
  193.         //    printf(\"%s %s\\n\",temp->pathname,temp->filename);
  194.             
  195.             char c[2]={\'/\'};
  196.             strcat(temp->pathname,c);
  197.             strcat(temp->pathname,temp->filename);
  198.             
  199.         //    printf(\"temp->pathname=%s\\n\",temp->pathname);
  200.             
  201.             strcpy(fileinfo,temp->pathname);
  202.             strcpy(filename,temp->filename);
  203.             
  204.             printf(\"fileinfo=%s\\n\",fileinfo);
  205.          // printf(\"filename=%s\\n\",filename);
  206.             
  207.             
  208.            
  209.          
  210.             
  211.                         
  212.              /*发送文件名*/
  213.             int sendbytes=0;
  214.             sendbytes=send(client_sockfd,filename,50,0);
  215.             printf(\"sendbytes=%d\\n\",sendbytes);
  216.             
  217.             //发送文件大小
  218.             int filesize=0;
  219.             int sendfsize;
  220.             lstat(fileinfo,&statbuff);
  221.             filesize=statbuff.st_size;
  222.             printf(\"filesize =%d\\n\",filesize);
  223.             sendfsize=send(client_sockfd,&filesize,4,0);
  224.         //    printf(\"sendfsize=%d\\n\",sendfsize);
  225.             
  226.             
  227.             
  228.             
  229.          /*发送文件内容*/
  230.             char buff[BUFFSIZE];
  231.             memset(buff,0,BUFFSIZE);
  232.                         
  233.             FILE * fp = fopen(fileinfo,\"r\");
  234.      
  235.              if(NULL == fp )
  236.              {
  237.                  printf(\"File:Not Found\\n\" );
  238.              }
  239.     
  240.              else
  241.              {
  242.                  int file_block_length = 0;
  243.         
  244.              while( (file_block_length = fread(buff,sizeof(char),BUFFSIZE,fp))>0)
  245.                 {
  246.                    // printf(\"file_block_length = %d\\n\",file_block_length);
  247.             
  248.                      if(send(client_sockfd,buff,file_block_length,0)<0)
  249.                         {
  250.                             printf(\"Send File Failed:\\n\");
  251.                             break;
  252.                         }
  253.         
  254.                     memset(buff,0,BUFFSIZE);
  255.                 }
  256.     
  257.                 fclose(fp);
  258.              }
  259.                                     
  260.              
  261.     temp=temp->next;    
  262.     }while(temp!=NULL);
  263.  
  264.     
  265.    
  266.        
  267.     printf(\"文件发送完毕\\n\");
  268.    }//end of child process
  269.    
  270.    if(pid>0)
  271.    {
  272.         close(client_sockfd);
  273.    }
  274.    
  275.   } //end of while(1)

  276. }


客户端:client.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <netinet/in.h>
  3. #include <sys/types.h> /* See NOTES */
  4. #include <sys/socket.h>
  5. #include <dirent.h>
  6. #include <string.h>
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. #include <netdb.h>
  10. #include <stdlib.h>

  11. #define IP_ADDR "192.168.1.14"

  12. int main()
  13. {
  14.     unsigned char filename[50];
  15.     int filesize;
  16.     unsigned char databuf[1000];
  17.     int sockfd;
  18.     struct sockaddr_in serv_addr;
  19.     
  20. //    struct hostent *host;
  21.     int i;
  22.     int lastsize=0;

  23. //    host = gethostbyname("localhost");

  24.     sockfd=socket(AF_INET,SOCK_STREAM,0);


  25.     serv_addr.sin_family = AF_INET;
  26.     serv_addr.sin_port = htons(9999);
  27.     //serv_addr.sin_addr = *((struct in_addr*)host->h_addr);
  28.     serv_addr.sin_addr.s_addr = inet_addr(IP_ADDR);
  29.     bzero(&(serv_addr.sin_zero),8);

  30.     if(connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(struct sockaddr))==-1){
  31.         perror("connect");
  32.         exit(1);
  33.     }

  34.        //接收文件数目
  35.    int count=0;
  36.    int countbyte;
  37.    countbyte=recv(sockfd,&count,4,0);
  38.    
  39.    printf("文件数目=%d\n",count);
  40.     
  41.     while(count--)
  42.     {    
  43.         i=recv(sockfd,filename,sizeof(filename),0); //接收文件名
  44.     //    printf("recv %d bytes\n",i);
  45.         printf("file name=%s\n",filename);
  46.         
  47.         i=recv(sockfd,&filesize,sizeof(filesize),0); //接收文件大小
  48.    //    printf("recv %d bytes\n",i);
  49.         printf("filesize=%d\n",filesize);
  50.         lastsize=filesize; //文件大小赋给变量
  51.         
  52.         //接收文件内容
  53.         FILE *fp = fopen(filename,"w");
  54.        
  55.     
  56.       
  57.         if(NULL == fp )
  58.         {
  59.             printf("File: Can Not Open To Write\n");
  60.             exit(1);
  61.          }
  62.         
  63.         i=0;
  64.         while(lastsize>0)
  65.         {
  66.             printf("lastsize=%d\n",lastsize);
  67.             if(lastsize>sizeof(databuf))
  68.             {
  69.                  i=recv(sockfd,databuf,sizeof(databuf),0);
  70.                  printf("接收字节i=%d\n",i);
  71.                 
  72.                  int write_length = fwrite(databuf,sizeof(char),i,fp);
  73.                  if (write_length<i)
  74.                      {
  75.                          printf("File:Write Failed\n");
  76.                            break;
  77.                      }
  78.                 
  79.              //    if(lastsize<5000) printf("recv %d bytes\n",i);
  80.             }
  81.             else
  82.             {
  83.                 printf("i'll recv %d byte only\n",lastsize);
  84.                 i=recv(sockfd,databuf,lastsize,0);
  85.                 printf("接收字节i=%d\n",i);
  86.                 
  87.                 
  88.              int write_length = fwrite(databuf,sizeof(char),i,fp);
  89.                 if (write_length<i)
  90.                      {
  91.                          printf("File:Write Failed\n");
  92.                            break;
  93.                      }
  94.                 
  95.          //        printf("*******recv %d bytes\n",i);
  96.             }
  97.             
  98.             lastsize=lastsize-i;
  99.             

  100.         }
  101.         
  102.        fclose(fp);
  103.        printf("该文件接收完毕\n");
  104.     }
  105.     return 0;
  106. }




阅读(2675) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~