• 2018-2019-1 20165318 实验三 实时系统


    2018-2019-1 20165318 实验三 实时系统

    任务一

    实验要求

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

    实验步骤

    1. 实现wc功能

    2. 实现客户端给服务器传文件功能

    3. 在客户端调用wc函数统计传过来的文件的单词个数

    4. 实现wc功能:使用「man 1 wc」查看wc命令的manpages


    • wc指令功能:统计指定文件中的字节数、字数、行数,并将统计结果显示输出。
    • wc指令格式:wc [选项] 文件...
    • wc指令描述:其中word字长是由空格分隔的非零长度序列。
    • wc命令参数:
      • -c 统计字节数。
      • -l 统计行数。
      • -m 统计字符数。这个标志不能与 -c 标志一起使用。
      • -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。
      • -L 打印最长行的长度。

    可以使用wc -w命令统计字数,但是字的定义是“空白、跳格或换行字符分隔的字符串”,和单词数不完全相同

    代码实现

    • 服务器
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    #define MYPORT 165318
    
    void main(){
    	int serverfd, clientfd;
    	struct sockaddr_in my_addr;
    	struct sockaddr_in remote_addr;
    
    	char buffer[BUFSIZ];
    	memset(&my_addr, 0, sizeof(my_addr));
    	my_addr.sin_family=AF_INET;
    	my_addr.sin_addr.s_addr=INADDR_ANY;
    	my_addr.sin_port=htons(MYPORT);
    
    	if((serverfd=socket(PF_INET, SOCK_STREAM, 0))==-1){
    		perror("socket");
    	}
    	
    	if(bind(serverfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))<0){
    		perror("bind");
    	}
    	listen(serverfd, 5);
    	int addrlen=sizeof(struct sockaddr_in);
    	while(1){
    		if((clientfd=accept(serverfd, (struct sockaddr *)&remote_addr, &addrlen))<0){
    			perror("accept");
    	}
    	printf("accept client %s
    ", inet_ntoa(remote_addr.sin_addr));
    	int len, i;
    	long wordscount=0;
    	int flag=1;
    	while(1){
    		if((len=recv(clientfd, buffer, 1024, 0))>0){
    			for(i=0; i<len; i++){
    				if(flag==0){
    					switch(buffer[i]){
    						case ' ':
    							wordscount++;
    							break;
    						case '
    ':
    							wordscount++;
    							break;
    						case '
    ':
    							wordscount++;
    							break;
    						default:
    							break;
    					}
    				}
    			if(buffer[i]== ' ' || buffer[i]=='
    ' || buffer[i]=='
    ') flag=1;
    			else flag=0;
    			}
    		}
    		if(len<1024) break;
    	}
    	send(clientfd, &wordscount, sizeof(long), 0);
    	close(clientfd);
    	}
    	close(serverfd);
    }
    
    • 客户端
    #include <stdio.h>  
    #include <sys/types.h>  
    #include <sys/socket.h>  
    #include <netinet/in.h>  
    #include <arpa/inet.h>  
    #include <string.h>
    
    #define MYPORT 165318
    
    void main(){
    	int clientfd;
    	struct sockaddr_in remote_addr;
    	char buffer[BUFSIZ];
    	memset(&remote_addr, 0 , sizeof(remote_addr));
    	remote_addr.sin_family=AF_INET;
    	remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    	remote_addr.sin_port=htons(MYPORT);
    
    	if((clientfd=socket(PF_INET,SOCK_STREAM,0))<0){  
    		perror("socket");  
    	}
    
    	if(connect(clientfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr))<0){
    		perror("connect");
    	}
    
    	int len;
    	FILE *fp;
    	char path[20];
    	gets(path);
    	fp=fopen(path, "r");
    	char readch;
    	int i=0;
    	while((readch=fgetc(fp))!=EOF){
    		if(i<1024){
    			buffer[i]=readch;
    			i++;
    		}
    		else{
    			i=0;
    			int n=send(clientfd, buffer, 1024, 0);
    		}
    	}
    	fclose(fp);
    	if(i!=0) 
    		send(clientfd, buffer, i, 0);
    	long wordscount;
    	recv(clientfd, &wordscount, sizeof(long), 0);
    	printf("%ld
    ", wordscount);
    	close(clientfd);
    }
    

    实验截图

    任务二

    实验要求

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

    实验步骤

    • 任务一中的客户端代码不需要改变,只需要改变服务器代码即可。
    • 服务器代码需要增加两个功能
      • 增加多线程
      • 使用同步互斥

    代码实现

    • 服务器端
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <pthread.h>
    
    #define MYPORT 165318
    pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
    int serverfd, clientfd;
    char buffer[BUFSIZ];
    
    void *wc(void *m){
    	pthread_mutex_lock( &counter_mutex );
    	int len, i;
    	long wordscount=0;
    	int flag=1;
    	while(1){
    		if((len=recv(clientfd, buffer, 1024, 0))>0){
    			for(i=0; i<len; i++){
    				if(flag==0){
    					switch(buffer[i]){
    						case ' ':
    							wordscount++;
    							break;
    						case '
    ':
    							wordscount++;
    							break;
    						case '
    ':
    							wordscount++;
    							break;
    						default:
    							break;
    					}
    				}
    				if(buffer[i]== ' ' || buffer[i]=='
    ' || buffer[i]=='
    ') 
    					flag=1;
    				else 
    					flag=0;
    			}
    		}
    		if(len<1024) 
    			break;
    	}
    	send(clientfd, &wordscount, sizeof(long), 0);
    	close(clientfd);
    	pthread_mutex_unlock( &counter_mutex );
    	return NULL;
    }
    void main(){
    	pthread_t t;
    	char arg[30];
    
    	struct sockaddr_in my_addr;
    	struct sockaddr_in remote_addr;
    
    	memset(&my_addr, 0, sizeof(my_addr));
    	my_addr.sin_family=AF_INET;
    	my_addr.sin_addr.s_addr=INADDR_ANY;
    	my_addr.sin_port=htons(MYPORT);
    
    	if((serverfd=socket(PF_INET, SOCK_STREAM, 0))==-1){
    		perror("socket");
    	}
    
    	if(bind(serverfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))<0){
    		perror("bind");
    	}
    	listen(serverfd, 5);
    	int addrlen=sizeof(struct sockaddr_in);
    	while(1){
    		if((clientfd=accept(serverfd, (struct sockaddr *)&remote_addr, &addrlen))<0){
    			perror("accept");
    		}
    		printf("accept client %s
    ", inet_ntoa(remote_addr.sin_addr));
    		pthread_create(&t, NULL, &wc, NULL);
    		pthread_join(&t, NULL);
    	}
    	close(serverfd);
    }
    
    • 客户端
    #include <stdio.h>  
    #include <sys/types.h>  
    #include <sys/socket.h>  
    #include <netinet/in.h>  
    #include <arpa/inet.h>  
    #include <string.h>
    
    #define MYPORT 165318
    
    void main(){
    	int clientfd;
    	struct sockaddr_in remote_addr;
    	char buffer[BUFSIZ];
    	memset(&remote_addr, 0 , sizeof(remote_addr));
    	remote_addr.sin_family=AF_INET;
    	remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    	remote_addr.sin_port=htons(MYPORT);
    
    	if((clientfd=socket(PF_INET,SOCK_STREAM,0))<0){  
    		perror("socket");  
    	}
    
    	if(connect(clientfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr))<0){
    		perror("connect");
    	}
    
    	int len;
    	FILE *fp;
    	char path[20];
    	gets(path);
    	fp=fopen(path, "r");
    	char readch;
    	int i=0;
    	while((readch=fgetc(fp))!=EOF){
    		if(i<1024){
    			buffer[i]=readch;
    			i++;
    		}
    		else{
    			i=0;
    			int n=send(clientfd, buffer, 1024, 0);
    		}
    	}
    	fclose(fp);
    	if(i!=0) 
    		send(clientfd, buffer, i, 0);
    	long wordscount;
    	recv(clientfd, &wordscount, sizeof(long), 0);
    	printf("%ld
    ", wordscount);
    	close(clientfd);
    }
    

    实验截图

    实验遇到的问题及解决方法

    • 问题:在进行任务二时,在服务器代码的头文件中有<pthread.h>,可是编译的时候却报错“对pthread_create未定义的引用“。

    • 解决方法:通过参考对pthread_create未定义的引用,因为pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时,在编译中要加-lpthread参数:gcc createThread.c -lpthread -o createThread. 加上这个以后编译成功!

  • 相关阅读:
    hive函数总结
    python判断文件和目录是否存在
    python中的参数
    写hive db的两种方法
    python中argparse模块的使用
    python数据持久存储:pickle模块的使用
    python读文件
    mysql 将时间戳直接转换成日期时间
    shell日期的应用
    [转]SQL UNION 和 UNION ALL 操作符
  • 原文地址:https://www.cnblogs.com/sunxiaoxuan/p/9975931.html
Copyright © 2020-2023  润新知