2017-2018-1 20155210 實驗三 實時系統
阿新 • • 發佈:2017-11-18
分享 指針 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 實驗三 實時系統