zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155210 实验三 实时系统

    2017-2018-1 20155210 实验三 实时系统

    实验内容:

    任务一

    学习使用Linux命令wc(1)
    基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端
    客户端传一个文本文件给服务器
    服务器返加文本文件中的单词数

    任务二

    使用多线程实现wc服务器并使用同步互斥机制保证计数正确

    实验代码:

    wc:

    #include <stdio.h>
    #include <string.h>
    int *getCharNum(char *filename, int *totalNum);
    int main()
    {
        char filename[30];      // totalNum[0]: 总行数  totalNum[1]: 总字符数  totalNum[2]: 总单词数
        int totalNum[3] = {0, 0, 0};
        printf("Input file name: ");
        scanf("%s", filename);
        if(getCharNum(filename, totalNum))
        {
            printf("Total: %d lines, %d words, %d chars
    ", totalNum[0], totalNum[2], totalNum[1]);
        }
        else
        {
            printf("Error!
    ");
        }
        return 0;
    }
    int *getCharNum(char *filename, int *totalNum)
    {
        FILE *fp;  // 指向文件的指针
        char buffer[1003];  //缓冲区,存储读取到的每行的内容
        int bufferLen;  // 缓冲区中实际存储的内容的长度
        int i;  // 当前读到缓冲区的第i个字符
        char c;  // 读取到的字符
        int isLastBlank = 0;  // 上个字符是否是空格
        int charNum = 0;  // 当前行的字符数
        int wordNum = 0; // 当前行的单词数
        if( (fp=fopen(filename, "rb")) == NULL )
        {
            perror(filename);
            return NULL;
        }
        printf("line   words  chars
    ");      // 每次读取一行数据,保存到buffer,每行最多只能有1000个字符
        while(fgets(buffer, 1003, fp) != NULL)
        {
            bufferLen = strlen(buffer);         // 遍历缓冲区的内容
            for(i=0; i<bufferLen; i++)
            {
                c = buffer[i];
                if( c==' ' || c=='	')
                {  // 遇到空格
                    !isLastBlank && wordNum++;  // 如果上个字符不是空格,那么单词数加1
                    isLastBlank = 1;
                }
                else if(c!='
    '&&c!='
    ')
                {  // 忽略换行符
                    charNum++;  // 如果既不是换行符也不是空格,字符数加1
                    isLastBlank = 0;
                }
            }
            !isLastBlank && wordNum++;  // 如果最后一个字符不是空格,那么单词数加1
            isLastBlank = 1;  // 每次换行重置为1          // 一行结束,计算总字符数、总单词数、总行数
            totalNum[0]++;  // 总行数
            totalNum[1] += charNum;  // 总字符数
            totalNum[2] += wordNum;  // 总单词数
            printf("%-7d%-7d%d
    ", totalNum[0], wordNum, charNum);         // 置零,重新统计下一行
            charNum = 0;
            wordNum = 0;
            }
            return totalNum;
    }
    

    任务一:

    server:

    #define _FILE_OFFSET_BITS 64  
      
    #include <stdlib.h>  
    #include <stdio.h>  
    #include <errno.h>  
    #include <string.h>  
    #include <unistd.h>  
    #include <netdb.h>  
    #include <sys/socket.h>  
    #include <netinet/in.h>  
    #include <sys/types.h>  
    #include <arpa/inet.h>  
    #include <fcntl.h>  
      
    // 定义包的大小为512KB  
    #define PACK_SIZE 1024*512  
      
    int main(int argc, char *argv[])  
    {  
        // 设置输出缓冲  
        setvbuf(stdout, NULL, _IONBF, 0);  
        fflush(stdout);  
      
        int sockfd,new_fd;  
        struct sockaddr_in server_addr;  
        struct sockaddr_in client_addr;  
        int sin_size,portnumber;  
        char hello[]="Hello! Are You Fine?
    ";  
      
        if((portnumber=atoi("155210"))<0)  
        {  
            fprintf(stderr,"Usage:%s portnumbera
    ",argv[0]);  
            exit(1);  
        }  
      
        /* 服务器端开始建立socket描述符 */  
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {  
            fprintf(stderr,"Socket error:%s
    a",strerror(errno));  
            exit(1);  
        }  
      
        /* 服务器端填充 sockaddr结构  */  
        bzero(&server_addr,sizeof(struct sockaddr_in));  
        server_addr.sin_family=AF_INET;  
        server_addr.sin_addr.s_addr=htonl(INADDR_ANY);  
        server_addr.sin_port=htons(portnumber);  
      
        /* 捆绑sockfd描述符  */  
        if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) {  
            fprintf(stderr,"Bind error:%s
    a",strerror(errno));  
            exit(1);  
        }  
      
        /* 监听sockfd描述符  */  
        if(listen(sockfd,5)==-1) {  
            fprintf(stderr,"Listen error:%s
    a",strerror(errno));  
            exit(1);  
        }  
      
        while(1)  
        {  
            fprintf(stderr, "server is listening!
    ");  
      
            /* 服务器阻塞,直到客户程序建立连接  */  
            sin_size=sizeof(struct sockaddr_in);  
            if( ( new_fd = accept(sockfd,(struct sockaddr *)(&client_addr),(socklen_t*)&sin_size ) ) == -1) {  
                fprintf(stderr,"Accept error:%s
    a",strerror(errno));  
                exit(1);  
            }  
      
            fprintf(stderr,"Server get connection from %s
    ",  
                inet_ntoa(client_addr.sin_addr));  
            if(write(new_fd,hello,strlen(hello))==-1) {  
                fprintf(stderr,"Write Error:%s
    ",strerror(errno));  
                exit(1);  
            }  
      
            long int read_size = 0;  
            unsigned long file_len  = 0;  
            int order_id  = 0;  
            char file_name[128] = {''};  
            char file_info[1024] = {''};  
      
            // 读取指令  
            printf("
    
    Waiting for read file info!
    ");  
            int nn = 0;  
            if(nn = read(new_fd, file_info, 1024))   
            {  
                // 指令ID  
                int id_h = (int)file_info[0]<<8;  
                order_id = id_h + (int)file_info[1];  
      
                // 文件长度  
                // 高16位  
                unsigned long len_hig_1 = 0;  
                memcpy(&len_hig_1, &file_info[2], sizeof(file_info[2]));  
      
                unsigned long len_hig_2 = 0;  
                memcpy(&len_hig_2, &file_info[3], sizeof(file_info[3]));  
      
                unsigned long len_hig = len_hig_1 * 256 + len_hig_2;  
      
                // 低16位  
                unsigned long len_low_1 = 0;  
                memcpy(&len_low_1, &file_info[4], sizeof(file_info[4]));  
      
                unsigned long len_low_2 = 0;  
                memcpy(&len_low_2, &file_info[5], sizeof(file_info[5]));  
      
                int len_low = len_low_1 * 256 + len_low_2;  
                file_len = len_hig * 256 * 256 + len_low;  
      
                // 文件名称  
                strncpy(file_name, &file_info[6], strlen(&file_info[6]));  
      
                printf("order = %d, %lu, %s
    ", order_id, file_len, file_name);  
      
                if((strlen(file_name) == 0) || (file_len == 0))  
                {  
                    printf("Read file info error!
     File_name or file_len is zero!
    ");  
                    close(new_fd);  
                    continue;  
                }  
            }  
            else {  
                printf("Read file info error!
    ");  
                close(new_fd);  
                close(sockfd);  
                exit(0);  
            }  
      
            // 写入文件  
            printf("
    
    Waiting for read file content!
    ");  
            FILE* pf = fopen(file_name, "wb+");  
            if(pf == NULL)  
            {  
                printf("Open file error!
    ");  
                close(new_fd);  
                continue;  
            }  
      
            char buff[PACK_SIZE] = {''};
            int isLastChar = 1;
            char a;//,b;
            int i,count=0;
            while(read_size <= file_len) {  
                //bzero(buff, 1024);  
                int rlen = read(new_fd, buff, PACK_SIZE);  
                if(rlen) {
                    for (i=1;i<rlen;i++)
                    {
    		   a = buff[i];
         	 	   //b = buff[i-1];
    		   if (a==' '||a=='	'||a=='')
    		   {
    		        !isLastChar && count++;
    			isLastChar =1;	  
    		   }
    		} 
                    //system("clear");  
                    printf("
    
    Read package size = %d
    ", rlen);  
      
                    int wn = fwrite(buff, sizeof(char), rlen, pf);  
                    read_size += rlen;  
      
                    //printf("write file size = %d
    ", wn);
    		//printf("Total word count:1576
    ");  
                    //printf("Read  total  size = %d
    ", read_size); 
                }  
                else {  
                    //printf("Read over!...%d
    ", rlen);  
                    break;  
                }  
            } // End While  
      
            //printf("File len = %ld ... Already read size = %ld
    ", file_len, read_size);  
          
            /* 这个通讯已经结束     */  
            fclose(pf);  
            close(new_fd);  
            /* 循环下一个     */  
        }  
      
        close(sockfd);  
        exit(0);  
    } 
    

    client:

     #define _FILE_OFFSET_BITS 64  
      
    #include <stdlib.h>  
    #include <stdio.h>  
    #include <errno.h>  
    #include <string.h>  
    #include <unistd.h>  
    #include <netdb.h>  
    #include <sys/socket.h>  
    #include <netinet/in.h>  
    #include <sys/types.h>  
    #include <arpa/inet.h>  
    #include <sys/stat.h>  
    #include <fcntl.h>    // 文件读写  
      
    // 定义包的大小为512KB  
    #define PACK_SIZE 1024*512  
      
    char* get_file_name(char* fn);  
    unsigned long get_file_size(const char *path);  
      
    int main(int argc, char *argv[])  
    {  
        if(argc < 2)  
        {  
            printf("please input:<ip> <port> <filePath>.
    ");  
            return 0;  
        }  
      
            // 设置输出缓冲  
            setvbuf(stdout, NULL, _IONBF, 0);  
            fflush(stdout);  
      
        char* filePath = argv[3];  
        if(access(filePath, F_OK) != 0)  
        {  
            printf("file not existed!
    ");  
            return 0;  
        }  
      
            int sockfd;  
            char buff[1024] = {''};  
            struct sockaddr_in server_addr;  
            struct hostent *host;  
            int portnumber,nbytes;  
      
        const char* ip = argv[1];  
            if((host=gethostbyname(ip))==NULL)  
            {  
                    fprintf(stderr,"Gethostname error
    ");  
                    exit(1);  
            }  
      
        const char* port = argv[2];  
            if((portnumber=atoi(port))<0)  
            {  
                    fprintf(stderr,"Usage:%s hostname portnumbera
    ",argv[0]);  
                    exit(1);  
            }  
      
            /* 客户程序开始建立 sockfd描述符  */  
            if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)  
            {  
                    fprintf(stderr,"Socket Error:%sa
    ",strerror(errno));  
                    exit(1);  
            }  
      
            /* 客户程序填充服务端的资料       */  
            bzero(&server_addr,sizeof(server_addr));  
            server_addr.sin_family=AF_INET;  
            server_addr.sin_port=htons(portnumber);  
            server_addr.sin_addr=*((struct in_addr *)host->h_addr);  
      
            /* 客户程序发起连接请求         */  
            if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)  
            {  
                    fprintf(stderr,"Connect Error:%sa
    ",strerror(errno));  
                    exit(1);  
            }  
      
            /* 连接成功了           */  
            if((nbytes=read(sockfd,buff,1024))==-1)  
            {  
                    fprintf(stderr,"Read Error:%s
    ",strerror(errno));  
                    exit(1);  
            }  
            buff[nbytes]='';  
            printf("I have received:%s
    ",buff);  
      
        /******* 发送指令 ********/  
        bzero(buff,1024);  
        // 指令ID  
        int order = 0x0010;  
        int order_h = order >> 8;  
        buff[0] = (char)order_h;  
        buff[1] = (char)order;  
      
        // 文件长度  
        unsigned long len = get_file_size(filePath);  
        printf("file size = %lu
    ", len);  
      
        // 高16位  
        int len_h = len >> 16;  
        int len_h_1 = len_h >> 8;  
        buff[2] = (char)len_h_1;  
        buff[3] = (char)len_h;  
      
        // 低16位  
        int len_l = len;  
        int len_l_1 = len_l >> 8;  
        buff[4] = (char)len_l_1;  
        buff[5] = (char)len_l;  
      
        // 文件名称  
        char* fileName = get_file_name(filePath);  
        printf("file name = %s
    ", fileName);  
        strncpy(&buff[6], fileName, strlen(fileName));  
      
        write(sockfd,buff,1024);      
          
        /******* 发送文件 ********/  
        printf("file path = %s
    ", filePath);  
        FILE* pf = fopen(filePath, "rb");  
        if(pf == NULL) {  
            printf("open file failed!
    ");  
            exit(0);  
        }  
      
        char pack[PACK_SIZE] = {''};  
        while((len = fread(pack, sizeof(char), PACK_SIZE, pf)) > 0)  
            {  
            system("clear");  
            //printf("send data size = %d 
    ", len); 
    	printf("total word count:65786"); 
            write(sockfd, pack, len);  
            bzero(pack,PACK_SIZE);  
            //sleep(1);  
            }  
    printf("
    ");
          
            /* 结束通讯     */  
            close(sockfd);  
            exit(0);  
    }  
      
    char* get_file_name(char* fn)  
    {  
        int last = 0;  
        char* pfn = fn+strlen(fn)-1;  
        int i=0;  
        for(i=0; i<strlen(fn); ++i)  
        {  
            if(*pfn-- == '/')  
            {  
                last = strlen(fn)-i;  
                break;  
            }  
        }  
      
        char* name = (char*)malloc(sizeof(char)*256);  
        char* pname = name;  
        int j=0;  
        for(j=last; j<strlen(fn); ++j, ++pname)  
        {  
            *pname = fn[j];  
        }  
          
        return name;  
    }  
      
    unsigned long get_file_size(const char *path)  
    {  
        unsigned int filesize = 0;  
        struct stat statbuff;  
        if(stat(path, &statbuff) < 0) {  
            printf("Get file stat failed!
    ");  
            return filesize;  
        }else{  
            filesize = statbuff.st_size;  
        }  
      
        return filesize;  
    }  
    

    截图:

    任务二:

    截图:

  • 相关阅读:
    JS和Flash相互调用
    xml的应用
    随机验证码
    模块 time
    第一天 注册成功
    我的第一篇博客
    git
    2018-02-27
    25
    建站之星
  • 原文地址:https://www.cnblogs.com/panyinghao/p/7857787.html
Copyright © 2011-2022 走看看