2017-2018-1 20155209 實驗三 實時系統
學習使用Linux命令wc(1)
基于Linux Socket程序設計實現wc(1)服務器(端口號是你學號的后6位)和客戶端
客戶端傳一個文本文件給服務器
服務器返加文本文件中的單詞數
- 使用man 1 wc查看wc
-
- 代碼實現如下:
- 客戶端
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>#define RIO_BUFSIZE 8192typedef struct{int rio_fd;int rio_cnt;char *rio_bufptr;char rio_buf[RIO_BUFSIZE];}rio_t;#define MAXLINE 200int main(int argc,char **argv){int clientfd,port;char *host,buf[MAXLINE];char sbuf[MAXLINE];char rbuf[MAXLINE];rio_t rio;char str1[MAXLINE]="客戶端IP:";char str2[MAXLINE]="服務器實現者學號:20155209”;char str3[MAXLINE]="當地時間:";FILE *fp;char filename[MAXLINE];if(argc!=3){fprintf(stderr,"usage:%s <host> <port>\n",argv[0]);exit(0);}host = argv[1];port = atoi(argv[2]);clientfd = open_clientfd(host,port);while(1){printf("輸入文件名(.txt):\n");gets(filename);fp = fopen(filename,"rb");while(!feof(fp)){fgets(sbuf,MAXLINE,fp);send(clientfd,sbuf,MAXLINE,0);bzero(sbuf,sizeof(sbuf)); }printf("%s",str1);puts(host);printf("%s",str2);putchar('\n');//printf("%s",str3);//puts(rbuf);fclose(fp);//sleep(1000);//recv(clientfd,rbuf,MAXLINE,0);//printf("傳輸完成,該文件單詞數為%s\n!",rbuf);//puts(rbuf);close(clientfd);exit(0);}}
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>#define MAXLINE 200
#define RIO_BUFSIZE 8192typedef struct{int rio_fd;int rio_cnt;char *rio_bufptr;char rio_buf[RIO_BUFSIZE];}rio_t;typedef struct sockaddr SA;typedef struct{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
}tm;void sigchld_handler(int sig){pid_t pid;int stat;while((pid = waitpid(-1,&stat,WNOHANG))>0){printf("child %d terminated\n",pid);}return;
}void itoa (int n,char s[])
{int i,j,sign;char temp[MAXLINE];if((sign=n)<0)//記錄符號n=-n;//使n成為正數i=0;do{temp[i++]=n%10+'0';//取下一個數字}while ((n/=10)>0);//刪除該數字if(sign<0)temp[i++]='-';for(j=0;j<i;j++){//生成的數字是逆序的,所以要逆序輸出s[j] = temp[i-j-1];}s[i] = '\0';
} int main(int argc,char **argv){int count=0,cnt=0,listenfd,connfd,port,clientlen;struct sockaddr_in clientaddr;struct hostent *hp;char *haddrp;char sbuf[MAXLINE];// char *bufp = sbuf;char rbuf[MAXLINE];rio_t rio;time_t lt;tm *local;char str1[MAXLINE]="客戶端IP:";char str2[MAXLINE]="服務器實現者學號:";char str3[MAXLINE]="當地時間:";FILE *fp = fopen("test.txt","wb");if(argc != 2){fprintf(stderr,"usage:%s <port>\n",argv[0]);exit(0);}port = atoi(argv[1]);signal(SIGCHLD,sigchld_handler);listenfd = open_listenfd(port);while(1){clientlen = sizeof(clientaddr);connfd = accept(listenfd,(SA *)&clientaddr,&clientlen);hp = gethostbyaddr((const char*)&clientaddr.sin_addr.s_addr,sizeof(clientaddr.sin_addr.s_addr),AF_INET);haddrp = inet_ntoa(clientaddr.sin_addr);printf("server connected to %s (%s)\n",hp->h_name,haddrp);if(fork() == 0){close(listenfd);/*lt = time(NULL); local = localtime(<);strftime(sbuf,64,"%Y-%m-%d %H:%M:%S",local);*/while(cnt = recv(connfd,rbuf,MAXLINE,0)){//printf("%d\n",recv(connfd,rbuf,MAXLINE,0)); fputs(rbuf,fp);bzero(rbuf,sizeof(rbuf));count += cnt;}//printf("傳輸成功!,該文件單詞數共%d\n!",count);fclose(fp);itoa(count,sbuf);//send(connfd,sbuf,MAXLINE,0);printf("該文件單詞數為%s!\n",sbuf);close(connfd);exit(0);}close(connfd);}
}
使用多線程實現wc服務器并使用同步互斥機制保證計數正確
上方提交代碼
下方提交測試
對比單線程版本的性能,并分析原因
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>#define RIO_BUFSIZE 8192typedef struct{int rio_fd;int rio_cnt;char *rio_bufptr;char rio_buf[RIO_BUFSIZE];}rio_t;#define MAXLINE 200int main(int argc,char **argv){int clientfd,port;char *host,buf[MAXLINE];char sbuf[MAXLINE];char rbuf[MAXLINE];rio_t rio;char str1[MAXLINE]="客戶端IP:";char str2[MAXLINE]="服務器實現者學號:20155209”;char str3[MAXLINE]="當地時間:";FILE *fp;char filename[MAXLINE];if(argc!=3){fprintf(stderr,"usage:%s <host> <port>\n",argv[0]);exit(0);}host = argv[1];port = atoi(argv[2]);clientfd = open_clientfd(host,port);while(1){printf("輸入文件名(.txt):\n");gets(filename);fp = fopen(filename,"rb");while(!feof(fp)){fgets(sbuf,MAXLINE,fp);send(clientfd,sbuf,MAXLINE,0);bzero(sbuf,sizeof(sbuf)); }printf("%s",str1);puts(host);printf("%s",str2);putchar('\n');//printf("%s",str3);//puts(rbuf);fclose(fp);//sleep(1000);//recv(clientfd,rbuf,MAXLINE,0);//printf("傳輸完成,該文件單詞數為%s\n!",rbuf);//puts(rbuf);close(clientfd);exit(0);}}
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>#define MAXLINE 200
#define RIO_BUFSIZE 8192typedef struct{int rio_fd;int rio_cnt;char *rio_bufptr;char rio_buf[RIO_BUFSIZE];}rio_t;typedef struct sockaddr SA;typedef struct{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
}tm;void itoa (int n,char s[]);void *thread(void *vargp);int main(int argc,char **argv){int listenfd,*connfdp,port;int clientlen;struct sockaddr_in clientaddr;struct hostent *hp;char *haddrp;pthread_t tid;if(argc != 2){fprintf(stderr,"usage:%s <port>\n",argv[0]);exit(0);}port = atoi(argv[1]);listenfd = open_listenfd(port);while(1){clientlen = sizeof(clientaddr);connfdp =malloc(sizeof(int));*connfdp = accept(listenfd,(SA *)&clientaddr,&clientlen);hp = gethostbyaddr((const char*)&clientaddr.sin_addr.s_addr,sizeof(clientaddr.sin_addr.s_addr),AF_INET);haddrp = inet_ntoa(clientaddr.sin_addr);printf("server connected to %s (%s)\n",hp->h_name,haddrp);pthread_create(&tid,NULL,thread,connfdp);pthread_join(tid,NULL);}
}void *thread(void *vargp){time_t lt;tm *local;char sbuf[MAXLINE];int cnt = 0,count = 0;char *fp = fopen("test.txt","wb");char rbuf[MAXLINE];int connfd = *((int*)vargp);free(vargp);pthread_detach(pthread_self());/*lt = time(NULL); local = localtime(<);strftime(sbuf,64,"%Y-%m-%d %H:%M:%S",local);send(connfd,sbuf,MAXLINE,0);*/
while(cnt = recv(connfd,rbuf,MAXLINE,0)){//printf("%d\n",recv(connfd,rbuf,MAXLINE,0)); fputs(rbuf,fp);bzero(rbuf,sizeof(rbuf));count += cnt;}//printf("傳輸成功!,該文件單詞數共%d\n!",count);fclose(fp);itoa(count,sbuf);//send(connfd,sbuf,MAXLINE,0);printf("該文件單詞數為%s!\n",sbuf);close(connfd);return NULL;
}void itoa (int n,char s[])
{int i,j,sign;char temp[MAXLINE];if((sign=n)<0)//記錄符號n=-n;//使n成為正數i=0;do{temp[i++]=n%10+'0';//取下一個數字}while ((n/=10)>0);//刪除該數字if(sign<0)temp[i++]='-';for(j=0;j<i;j++){//生成的數字是逆序的,所以要逆序輸出s[j] = temp[i-j-1];}s[i] = '\0';
}
轉載于:https://www.cnblogs.com/lhyhahaha/p/7862818.html
總結
以上是生活随笔為你收集整理的2017-2018-1 20155209 实验三 实时系统的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。