天天看點

linux下c程式設計——socket目錄統計

實驗内容

可執行程式有一個參數,如果這個參數是一個檔案名,

我們輸出這個檔案的大小,如果是一個目錄,

統計這個目錄(含多級子目錄)的如下資訊:

a.該目錄中普通檔案數量

b.該目錄中連結檔案數量

c.該目錄中子目錄數量,每個子目錄的目錄深度,

每個子目錄中普通檔案的數量,每個子目錄中連結檔案的數量

d.每個檔案的大小(位元組數)

e.将上述結果發送到伺服器,伺服器接收到資料後,

把資料寫入一個文本檔案

流程分析圖:

linux下c程式設計——socket目錄統計

下附源碼

用戶端

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<dirent.h>

#define SERVPORT 8888 
#define MAXDATASIZE 2000
int file_count=0;
int link_count=0;
int Dir_count=0;
int deep = 0;
int flag=0;
int i = 0;
int j = 0;
char buf[MAXDATASIZE];
char buf1[MAXDATASIZE];
char readCount[MAXDATASIZE];
void readFileList(char *Path);
void readFileCount(char *Path);

int main(int argc,char *argv[]){ 
	 
	char sss[MAXDATASIZE];
	char sum[2000];
	memset(sss,0,MAXDATASIZE);
	memset(sum,0,1000);
	readFileList(argv[1]);
	readFileCount(argv[1]);
	sprintf(sss,"[%s] 總檔案數量為:%d\t總符号連結檔案數量為:%d\t總目錄數量為:%d\n",argv[1],file_count,link_count,Dir_count);
	strcat(sum,buf);
	strcat(sum,buf1);
	strcat(sum,readCount);
	strcat(sum,"\n");
	strcat(sum,sss);
	int sockfd,sendbytes=0; 
	
	struct sockaddr_in serv_addr; 
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1){ 
		perror("socket"); 
		exit(1); 
	} 
	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family=AF_INET; 
	serv_addr.sin_port=htons(SERVPORT); 
	serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))== -1){ 
		perror("connect"); 
		exit(1); 
	}
	while(1)  
  	{  
		if((sendbytes=write(sockfd,sum,MAXDATASIZE))== -1){ 
		perror("send"); 
		exit(1); 
		}
		break; 
	}	
	close(sockfd);  
	return 0;
} 
void readFileList(char *Path)
{
 	DIR *dir;
   	struct dirent *ptr;
	struct stat statbuf;
	char base[100]; 
	
	memset(base,0,100);
	if(lstat(Path,&statbuf)<0)
		perror("lstat:");
	 if(S_ISDIR(statbuf.st_mode)){
		
		dir=opendir(Path);
		
		while ((ptr=readdir(dir)) != NULL)
   		 {		
			
					flag=1;
					if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0)
		 	   		 continue;
				Dir_count++;
				strcpy(base,Path);
				strcat(base,"/");
				strcat(base,ptr->d_name); 
			        readFileList(base);
			}
		
			closedir(dir);
		  } else if(S_ISREG(statbuf.st_mode)){
			file_count++;
			if(flag==1)
				Dir_count--;
			char r[100];
			sprintf(r,"[%s] 下的檔案大小為:%ld\n",Path,statbuf.st_size);
			strcat(buf,r);
			printf("[%s] 下的檔案大小為:%ld\n",Path,statbuf.st_size);
		 }else if(S_ISLNK(statbuf.st_mode)){
			link_count++;
			char l[100];
			sprintf(l,"[%s] 下的符号連結檔案大小為:%ld\n\n",Path,statbuf.st_size);
			strcat(buf1,l);
			printf("[%s] 下的符号連結檔案大小為:%ld\n",Path,statbuf.st_size);
		 } 
		
}

void readFileCount(char *Path)
{
    DIR *dir;
    struct dirent *ptr;
    char base[100];
     char path1[50];
        strcpy(path1,Path);
	    deep++;
    if ((dir=opendir(Path)) == NULL)
    {  
	return ;
    }
	  while ((ptr=readdir(dir)) != NULL)
    {
	 
        if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0)
              continue;
	else if(ptr->d_type == 8)   
 			i++;
	else if(ptr->d_type == 10) 
			j++;  
        else if(ptr->d_type == 4)  
        {
					char str1[50],str2[50];
					strcpy(str1,Path);
					strcpy(str2,path1);
					if(strcmp(str1,str2)!=0)
					{deep++;}
	    
            strcpy(base,Path);
            strcat(base,"/");
            strcat(base,ptr->d_name); 
	  
            readFileCount(base);
        }
    }	
	char rf[1000];
	memset(rf,0,1000);
	sprintf(rf,"%s路徑下的檔案個數為:%d,符号連結檔案個數為:%d,目錄深度為:%d\n",Path,i,j,deep);
	printf("%s路徑下的檔案個數為:%d,符号連結檔案個數為:%d,目錄深度為:%d\n",Path,i,j,deep);
	strcat(readCount,rf);
	i=0;j=0;deep--;
    closedir(dir);
  
}

           

服務端

#include <sys/socket.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <netdb.h>
#include <arpa/inet.h>
#include<sys/types.h>
#include<fcntl.h>

#define SERVER_IP "127.0.0.1"  
#define SERVER_PORT 8888 
  
  
#define MAX_RECV_LEN 2048 
#define MAX_CLIENT_NUM 20 
#define BACK_LOG 20  
  
  
static int running = 1;  
  
  
int main(int argc, char *argv[])  
{  
    int sock_fd = -1;  
    int ret = -1;  
    struct sockaddr_in serv_addr;  
    struct sockaddr_in cli_addr;  
    socklen_t serv_addr_len = 0;  
    socklen_t cli_addr_len = 0;  
    int client_fd[MAX_CLIENT_NUM];  
    char recv_buf[MAX_RECV_LEN];  
    int new_conn_fd = -1;  
    int i = 0;  
    int max_fd = -1;  
    int num = -1;  
    struct timeval timeout;  
  
  
    fd_set read_set;  
    fd_set write_set;  
    fd_set select_read_set;  
  
  
    FD_ZERO(&read_set);  
    FD_ZERO(&write_set);  
    FD_ZERO(&select_read_set);  
  
    for (i = 0; i < MAX_CLIENT_NUM; i++)  
    {  
        client_fd[i] = -1;  
    }   
  
    memset(&serv_addr, 0, sizeof(serv_addr));  
    memset(&cli_addr, 0, sizeof(cli_addr));  
  
  
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);  
    if (sock_fd < 0)  
    {  
        perror("Fail to socket");  
        exit(1);  
    }  
  
  
    serv_addr.sin_family = AF_INET;  
    serv_addr.sin_port = htons(SERVER_PORT);  
    serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);  
  
  
    unsigned int value = 1;  
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,(void *)&value, sizeof(value)) < 0)  
    {  
        perror("Fail to setsockopt");  
        exit(1);  
    }  
  
  
    serv_addr_len = sizeof(serv_addr);  
    if (bind(sock_fd, (struct sockaddr*)&serv_addr, serv_addr_len) < 0)  
    {  
        perror("Fail to bind");  
        exit(1);  
    }  
    if (listen(sock_fd, BACK_LOG) < 0)  
    {  
        perror("Fail to listen");  
        exit(1);  
    }  
  
    char buf[1024];  
    max_fd = sock_fd;  
    int len;  
    FD_SET(sock_fd, &read_set);  
    while (running)  
    {  
        timeout.tv_sec = 5;  
        timeout.tv_usec = 0;  
  
  
        max_fd = sock_fd;  
        for (i = 0; i < MAX_CLIENT_NUM; i++)  
        {  
            if (max_fd < client_fd[i])  
            {  
                max_fd = client_fd[i];  
            }  
        }  
  
  
        select_read_set = read_set;  
        ret = select(max_fd + 1, &select_read_set, NULL, NULL, &timeout);  
        if (ret == 0)  
        {  
            printf("timeout\n");  
        }  
        else if (ret < 0)  
        {  
            printf("error occur\n");  
        }  
        else  
        {  
            if (FD_ISSET(sock_fd, &select_read_set))  
            {  
                printf("new client comes\n");  
                len = sizeof(cli_addr);  
                new_conn_fd = accept(sock_fd, (struct sockaddr*)&cli_addr, &len);  
                if (new_conn_fd < 0)  
                {  
                    perror("Fail to accept");  
                    exit(1);  
                }  
                else  
                {  
                    for (i = 0; i < MAX_CLIENT_NUM; i++)  
                    {  
                        if (client_fd[i] == -1)  
                        {  
                            client_fd[i] = new_conn_fd;  
                            FD_SET(new_conn_fd, &read_set);  
                            break;  
                        }  
                        if (max_fd < new_conn_fd)  
                        {  
                            max_fd = new_conn_fd;  
                        }  
                    }  
				 num = read(client_fd[i], recv_buf, MAX_RECV_LEN);  
		              	  if (num < 0)  
		              	  {  
		                    printf("Client(%d) left\n", client_fd[i]);  
		                    FD_CLR(client_fd[i], &read_set);  
		                    close(client_fd[i]);  
		                    client_fd[i] = -1;  
		             	   } else{ 
					printf("接收到的資料:\n%s",recv_buf);
					int fd;
					fd=open("dazuoye_test",O_CREAT|O_RDWR,S_IRWXU);
					write(fd,recv_buf,sizeof(recv_buf));
					printf("write success!\n");
					close(fd);
			}  
                }  
            }  
         
        }  
    }  
    return 0;  
}