1. 程式人生 > >2017-2018-1 20155210 實驗三 實時系統

2017-2018-1 20155210 實驗三 實時系統

分享 指針 sta byte gethostby stc src += error:

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\n", totalNum[0], totalNum[2], totalNum[1]);
    }
    else
    {
        printf("Error!\n");
    }
    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\n");      // 每次讀取一行數據,保存到buffer,每行最多只能有1000個字符
    while(fgets(buffer, 1003, fp) != NULL)
    {
        bufferLen = strlen(buffer);         // 遍歷緩沖區的內容
        for(i=0; i<bufferLen; i++)
        {
            c = buffer[i];
            if( c==‘ ‘ || c==‘\t‘)
            {  // 遇到空格
                !isLastBlank && wordNum++;  // 如果上個字符不是空格,那麽單詞數加1
                isLastBlank = 1;
            }
            else if(c!=‘\n‘&&c!=‘\r‘)
            {  // 忽略換行符
                charNum++;  // 如果既不是換行符也不是空格,字符數加1
                isLastBlank = 0;
            }
        }
        !isLastBlank && wordNum++;  // 如果最後一個字符不是空格,那麽單詞數加1
        isLastBlank = 1;  // 每次換行重置為1          // 一行結束,計算總字符數、總單詞數、總行數
        totalNum[0]++;  // 總行數
        totalNum[1] += charNum;  // 總字符數
        totalNum[2] += wordNum;  // 總單詞數
        printf("%-7d%-7d%d\n", 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?\n";  
  
    if((portnumber=atoi("155210"))<0)  
    {  
        fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);  
        exit(1);  
    }  
  
    /* 服務器端開始建立socket描述符 */  
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {  
        fprintf(stderr,"Socket error:%s\n\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\n\a",strerror(errno));  
        exit(1);  
    }  
  
    /* 監聽sockfd描述符  */  
    if(listen(sockfd,5)==-1) {  
        fprintf(stderr,"Listen error:%s\n\a",strerror(errno));  
        exit(1);  
    }  
  
    while(1)  
    {  
        fprintf(stderr, "server is listening!\n");  
  
        /* 服務器阻塞,直到客戶程序建立連接  */  
        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\n\a",strerror(errno));  
            exit(1);  
        }  
  
        fprintf(stderr,"Server get connection from %s\n",  
            inet_ntoa(client_addr.sin_addr));  
        if(write(new_fd,hello,strlen(hello))==-1) {  
            fprintf(stderr,"Write Error:%s\n",strerror(errno));  
            exit(1);  
        }  
  
        long int read_size = 0;  
        unsigned long file_len  = 0;  
        int order_id  = 0;  
        char file_name[128] = {‘\0‘};  
        char file_info[1024] = {‘\0‘};  
  
        // 讀取指令  
        printf("\n\nWaiting for read file info!\n");  
        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\n", order_id, file_len, file_name);  
  
            if((strlen(file_name) == 0) || (file_len == 0))  
            {  
                printf("Read file info error!\n File_name or file_len is zero!\n");  
                close(new_fd);  
                continue;  
            }  
        }  
        else {  
            printf("Read file info error!\n");  
            close(new_fd);  
            close(sockfd);  
            exit(0);  
        }  
  
        // 寫入文件  
        printf("\n\nWaiting for read file content!\n");  
        FILE* pf = fopen(file_name, "wb+");  
        if(pf == NULL)  
        {  
            printf("Open file error!\n");  
            close(new_fd);  
            continue;  
        }  
  
        char buff[PACK_SIZE] = {‘\0‘};
        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==‘\t‘||a==‘\0‘)
           {
                !isLastChar && count++;
            isLastChar =1;    
           }
        } 
                //system("clear");  
                printf("\n\nRead package size = %d\n", rlen);  
  
                int wn = fwrite(buff, sizeof(char), rlen, pf);  
                read_size += rlen;  
  
                //printf("write file size = %d\n", wn);
        //printf("Total word count:1576\n");  
                //printf("Read  total  size = %d\n", read_size); 
            }  
            else {  
                //printf("Read over!...%d\n", rlen);  
                break;  
            }  
        } // End While  
  
        //printf("File len = %ld ... Already read size = %ld\n", 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>.\n");  
        return 0;  
    }  
  
        // 設置輸出緩沖  
        setvbuf(stdout, NULL, _IONBF, 0);  
        fflush(stdout);  
  
    char* filePath = argv[3];  
    if(access(filePath, F_OK) != 0)  
    {  
        printf("file not existed!\n");  
        return 0;  
    }  
  
        int sockfd;  
        char buff[1024] = {‘\0‘};  
        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\n");  
                exit(1);  
        }  
  
    const char* port = argv[2];  
        if((portnumber=atoi(port))<0)  
        {  
                fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);  
                exit(1);  
        }  
  
        /* 客戶程序開始建立 sockfd描述符  */  
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)  
        {  
                fprintf(stderr,"Socket Error:%s\a\n",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:%s\a\n",strerror(errno));  
                exit(1);  
        }  
  
        /* 連接成功了           */  
        if((nbytes=read(sockfd,buff,1024))==-1)  
        {  
                fprintf(stderr,"Read Error:%s\n",strerror(errno));  
                exit(1);  
        }  
        buff[nbytes]=‘\0‘;  
        printf("I have received:%s\n",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\n", 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\n", fileName);  
    strncpy(&buff[6], fileName, strlen(fileName));  
  
    write(sockfd,buff,1024);      
      
    /******* 發送文件 ********/  
    printf("file path = %s\n", filePath);  
    FILE* pf = fopen(filePath, "rb");  
    if(pf == NULL) {  
        printf("open file failed!\n");  
        exit(0);  
    }  
  
    char pack[PACK_SIZE] = {‘\0‘};  
    while((len = fread(pack, sizeof(char), PACK_SIZE, pf)) > 0)  
        {  
        system("clear");  
        //printf("send data size = %d \n", len); 
    printf("total word count:65786"); 
        write(sockfd, pack, len);  
        bzero(pack,PACK_SIZE);  
        //sleep(1);  
        }  
printf("\n");
      
        /* 結束通訊     */  
        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!\n");  
        return filesize;  
    }else{  
        filesize = statbuff.st_size;  
    }  
  
    return filesize;  
}  

截圖:

技術分享圖片

任務二:

截圖:

技術分享圖片

2017-2018-1 20155210 實驗三 實時系統