• 2019-2020-1 20175212童皓桢《信息安全系统设计》 实验三并发程序


    2019-2020-1 20175212童皓桢《信息安全系统设计》 实验三并发程序

    并发程序-1

    实验要求

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

    实验步骤

    1. 使用man wc学习wc命令的功能用法
      在这里插入图片描述
    2. 用socket编程实现
    client.c
    
    #include<netinet/in.h>   // sockaddr_in  
    
    #include<sys/types.h>    // socket  
    
    #include<sys/socket.h>   // socket  
    
    #include<stdio.h>        // printf  
    
    #include<stdlib.h>       // exit  
    
    #include<string.h>       // bzero  
    
    #include <arpa/inet.h>
    
    #include <unistd.h>
    
    #include "head.h"
    
    
    
    #define SERVER_PORT 5212
    
    #define BUFFER_SIZE 1024  
    
    #define FILE_NAME_MAX_SIZE 512  
    
    #define BEGIN 1;
    
    
    
    int main()  
    
    {
    
    	struct sockaddr_in client_addr;  
    
    	bzero(&client_addr, sizeof(client_addr));  
    
    	client_addr.sin_family = AF_INET;  
    
    	client_addr.sin_addr.s_addr = htons(INADDR_ANY);  
    
    	client_addr.sin_port = htons(0);  
    
    	int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);  
    
    	if(client_socket_fd < 0)  
    
    	{  
    
        		perror("Create Socket Failed!");  
    
        		exit(1);  
    
    	}  
    
    	if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))  
    
    	{  
    
        		perror("Client Bind Failed!");  
    
        		exit(1);  
    
    	}
    
    	struct sockaddr_in server_addr;  
    
    	bzero(&server_addr, sizeof(server_addr));  
    
    	server_addr.sin_family = AF_INET;  
    
    	if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0)  
    
    	{  
    
        		perror("Server IP Address Error!");  
    
        		exit(1);  
    
    	}  
    
    	server_addr.sin_port = htons(SERVER_PORT);  
    
    	socklen_t server_addr_length = sizeof(server_addr);  
    
    	if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)  
    
    	{  
    
        		perror("Can Not Connect To Server IP!");  
    
        		exit(0);  
    
    	}  
    
    	char file_name[FILE_NAME_MAX_SIZE+1];  
    
    	bzero(file_name, FILE_NAME_MAX_SIZE+1);  
    
    	printf("Please Input File Name On Client: ");
    
    	scanf("%s", file_name);  
    
    	char buffer[BUFFER_SIZE];  
    
    	bzero(buffer, BUFFER_SIZE);  
    
    	strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));  
    
    	if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)  
    
    	{  
    
        		perror("Send File Name Failed!");  
    
        		exit(1);  
    
    	}
    
        	FILE *fp = fopen(file_name, "r");  
    
        	if(NULL == fp)  
    
        	{  
    
            	printf("File: %s Not Found!
    ", file_name);  
    
        	}  
    
        	else  
    
        	{  
    
            	bzero(buffer, BUFFER_SIZE);  
    
            	int length = 0;  
    
            	while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
    
            	{
    
                		if(send(client_socket_fd, buffer, length, 0) < 0)  
    
                		{  
    
                    		printf("Send File: %s Failed!/n", file_name);  
    
                    		break;  
    
                		}  
    
                		bzero(buffer, BUFFER_SIZE);  
    
            	}  
    
    		printf("Send File: %s Successful!
    ", file_name);
    
    		printf("The File has %d words.
    ",wcfunc(file_name));	  
    
        	}  
    
    /*
    
    	char s[50];
    
    	scanf("%s",s);
    
    	send(client_socket_fd,"OK",50,0);
    
    
    
    	char recvdata[sizeof(int)+1];
    
    	recv(client_socket_fd,recvdata,sizeof(int),0);
    
    	recvdata[sizeof(int)]='';
    
    	int words=atoi(recvdata);*/
    
    	fclose(fp);
    
    	close(client_socket_fd);  
    
    	return 0;  
    
    }
    
    
    
    int wcfunc(char *file_name)
    
    {
    
    	int t;
    
    	int w = 0;
    
    	int state = 0;
    
    	FILE *in;
    
    	if((in = fopen(file_name,"r"))==NULL)
    
    	{
    
    		printf("wc %s:no this file or dir
    ",file_name);
    
    		return 0;
    
    	}
    
    	while((t=fgetc(in))!=EOF)
    
    	{
    
    		
    
    		if(t=='
    '||t==' '||t=='
    ') {
    
                		state = 0;
    
                		continue;
    
            	} else {
    
                		if(state == 0) {
    
                    	state = 1;
    
                    	w++;
    
               		}
    
                		continue;
    
            	}
    
    	}
    
    	return w;
    
    }
    
    server.c
    
    #include<netinet/in.h>  // sockaddr_in  
    
    #include<sys/types.h>   // socket  
    
    #include<sys/socket.h>  // socket  
    
    #include<stdio.h>       // printf  
    
    #include<stdlib.h>      // exit  
    
    #include<string.h>      // bzero  
    
    #include <unistd.h>
    
    
    
    #define SERVER_PORT 5212
    
    #define LENGTH_OF_LISTEN_QUEUE 20  
    
    #define BUFFER_SIZE 1024
    
    #define FILE_NAME_MAX_SIZE 512  
    
    #define BEGIN 1; 
    
    
    
    int main(void)  
    
    {  
    
    
    
    	struct sockaddr_in server_addr;  
    
    	bzero(&server_addr, sizeof(server_addr));  
    
    	server_addr.sin_family = AF_INET;  
    
    	server_addr.sin_addr.s_addr = htons(INADDR_ANY);  
    
    	server_addr.sin_port = htons(SERVER_PORT);  
    
    
    
    	int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);  
    
    	if(server_socket_fd < 0)  
    
    	{  
    
    		perror("Create Socket Failed!");  
    
    	    	exit(1);  
    
    	}  
    
    	int opt = 1;  
    
    	setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
    
    
    
    	if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))  
    
    	{  
    
    	    	perror("Server Bind Failed!");  
    
    	    	exit(1);  
    
    	}  
    
    	    
    
    	if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))  
    
    	{  
    
    	    	perror("Server Listen Failed!");  
    
    	    	exit(1);  
    
    	}  
    
    
    
    	while(1)  
    
    	{  
    
    	    	struct sockaddr_in client_addr;  
    
    	    	socklen_t client_addr_length = sizeof(client_addr);  
    
    
    
    	    	int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);  
    
    	    	if(new_server_socket_fd < 0)  
    
    	    	{  
    
    			perror("Server Accept Failed!");  
    
    			break;  
    
    	    	}  
    
    
    
    
    
    		char buffer[BUFFER_SIZE];  
    
    		bzero(buffer, BUFFER_SIZE);  
    
    		if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0)  
    
    		{  
    
    			perror("Server Recieve Data Failed!");  
    
    			break;  
    
    		}  
    
    
    
    
    
    	    	char file_name[FILE_NAME_MAX_SIZE+1];  
    
    	    	bzero(file_name, FILE_NAME_MAX_SIZE+1);  
    
    	    	strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));  
    
    		printf("%s
    ", file_name);  
    
    
    
    	    	FILE *fp = fopen(file_name, "w");  
    
    	    	if(NULL == fp)  
    
    	    	{  
    
    			printf("File: %s Can Not Open To Write
    ", file_name);  
    
    			exit(1);  
    
    	    	}  
    
    
    
    
    
    	    	bzero(buffer, BUFFER_SIZE);  
    
    	    	int length = 0;  
    
    	    	while((length = recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)  
    
    	    	{  
    
    		    	if(strcmp(buffer,"OK")==0) 
    
    				break;
    
    			if(fwrite(buffer, sizeof(char), length, fp) < length)  
    
    			{  
    
    			    	printf("File: %s Write Failed!
    ", file_name);  
    
    			    	break;  
    
    			}  
    
    			bzero(buffer, BUFFER_SIZE);  
    
    		}  
    
    
    
    	    	printf("Receive File: %s From Client Successful!
    ", file_name);  
    
    	    	fclose(fp);
    
    
    
    		int words=0;
    
    		char s[100];
    
    		FILE *fp2;
    
    		if((fp2=fopen(file_name,"r"))==NULL)
    
    		{
    
    	    		printf("ERROR!
    ");
    
    	    		exit(0);
    
    		}
    
    		while(fscanf(fp2,"%s",s)!=EOF)
    
    	    	words++;
    
    		fclose(fp2);
    
    		printf("%d words.
    ",words);
    
    
    
    		char sendbuf[50];
    
    		sprintf(sendbuf,"%d",words);
    
    		send(new_server_socket_fd,sendbuf,50,0);
    
    	    	close(new_server_socket_fd);  
    
    	}
    
    	close(server_socket_fd);  
    
    	return 0;  
    
    }
    

    在这里插入图片描述
    3. 使用wc功能检查
    在这里插入图片描述

    并发程序-2

    实验要求

    • 使用多线程实现wc服务器并使用同步互斥机制保证计数正确
    • 对比单线程版本的性能,并分析原因

    实验步骤

    1. 使用socket编程
    clinet.c
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <string.h>
    
    #include <fcntl.h>
    
    #include <unistd.h>
    
    #include <pthread.h>
    
    #include <sys/stat.h>
    
    #include <sys/types.h>
    
    #include <sys/socket.h>
    
    #include <arpa/inet.h>
    
    #include "head.h"
    
    #define BUFFER_SIZE 1024  
    
    #define FILE_NAME_MAX_SIZE 512 
    
    
    
    static void usage(const char* proc)
    
    {
    
        printf("%s[server_ip][server_port]
    ", proc);
    
    }
    
    
    
    //./client server_ip, server_port
    
    int main(int argc, char* argv[])
    
    {
    
        if(argc != 3)
    
        {
    
            usage(argv[0]);
    
            return 1;
    
        }
    
        //1.创建sock
    
        int sock = socket(AF_INET, SOCK_STREAM, 0);
    
        if(sock < 0)
    
        {
    
            perror("socket");
    
            return 2;
    
        }
    
        //2.connect
    
        struct sockaddr_in server;
    
        server.sin_family = AF_INET;
    
        server.sin_port = htons(atoi(argv[2]));
    
        //将点分十进制的字符串转换成能在网络上传输的网络号
    
        server.sin_addr.s_addr = inet_addr(argv[1]);
    
        //调用connect,第一个参数是客户端的socket套接字,第二个参数是服务器端套接字
    
        if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
    
        {
    
            perror("connect");
    
            return 2;
    
        }
    
        /*//先写后读
    
        char buf[1024];
    
        while(1)
    
        {
    
            printf("Please enter# ");
    
            fflush(stdout);
    
            //读取标准输入键盘中的数据
    
            ssize_t s = read(0, buf, sizeof(buf) - 1);
    
            if(s > 0)
    
            {
    
                buf[s - 1] = 0;
    
                //将buf中的内容写到套接字中
    
                write(sock, buf, strlen(buf));
    
                //读取服务器的响应
    
                ssize_t _s = read(sock, buf, sizeof(buf)-1);
    
                if(_s > 0)
    
                {
    
                    buf[_s] = 0;
    
                    printf("server ech0# %s
    ", buf);
    
                }
    
            }
    
        }*/
    
        char file_name[FILE_NAME_MAX_SIZE+1];  
    
        bzero(file_name, FILE_NAME_MAX_SIZE+1);  
    
        printf("Please Input File Name On Client: ");
    
        scanf("%s", file_name);  
    
        char buffer[BUFFER_SIZE];  
    
        bzero(buffer, BUFFER_SIZE);  
    
        strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));  
    
        if(send(sock, buffer, BUFFER_SIZE, 0) < 0)  
    
        {
    
    	perror("Send File Name Failed!");
    
    	exit(1);  
    
        }
    
        FILE *fp = fopen(file_name, "r");  
    
        if(NULL == fp)  
    
        {  
    
           	printf("File: %s Not Found!
    ", file_name);  
    
        }  
    
        else  
    
        {  
    
           	bzero(buffer, BUFFER_SIZE);  
    
           	int length = 0;  
    
           	while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
    
           	{
    
        	    if(send(sock, buffer, length, 0) < 0)  
    
                {  
    
                 	printf("Send File: %s Failed!/n", file_name);  
    
                    break;  
    
                }  
    
                bzero(buffer, BUFFER_SIZE);  
    
            }  
    
    	printf("Send File: %s Successful!
    ", file_name);
    
    	printf("The File has %d words.
    ",wcfunc(file_name));	  
    
        }
    
        fclose(fp);
    
        close(sock);
    
        return 0;
    
    }
    
    
    
    int wcfunc(char *file_name)
    
    {
    
    	int t;
    
    	int w = 0;
    
    	int state = 0;
    
    	FILE *in;
    
    	if((in = fopen(file_name,"r"))==NULL)
    
    	{
    
    		printf("wc %s:no this file or dir
    ",file_name);
    
    		return 0;
    
    	}
    
    	while((t=fgetc(in))!=EOF)
    
    	{
    
    		
    
    		if(t=='
    '||t==' '||t=='
    ') {
    
                		state = 0;
    
                		continue;
    
            	} else {
    
                		if(state == 0) {
    
                    	state = 1;
    
                    	w++;
    
               		}
    
                		continue;
    
            	}
    
    	}
    
    	return w;
    
    }
    
    server.c
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <string.h>
    
    #include <unistd.h>
    
    #include <fcntl.h>
    
    #include <pthread.h>
    
    #include <sys/stat.h>
    
    #include <sys/types.h>
    
    #include <sys/socket.h>
    
    #include <arpa/inet.h>
    
    #define BUFFER_SIZE 1024
    
    #define FILE_NAME_MAX_SIZE 512
    
    static void Usage(char* proc)
    
    {
    
        printf("%s[local_ip], [local_port]
    ", proc);
    
    }
    
    int startup(char* _ip, int _port)
    
    {
    
        int sock = socket(AF_INET, SOCK_STREAM, 0);
    
        if(sock < 0)
    
        {
    
            perror("socket");
    
            return 1;
    
        }
    
        struct sockaddr_in local;//初始化协议地址
    
        local.sin_family = AF_INET;
    
        local.sin_port = htons(_port);
    
        local.sin_addr.s_addr = inet_addr(_ip);
    
        //将套接字和tcp服务绑定(服务端ip地址)
    
        if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)
    
        {
    
            perror("bind");
    
            exit(3);
    
        }
    
        //监听这个套接字,监听指定端口,第二个参数表示可以排队连接的最大个数
    
        if(listen(sock, 5) < 0)
    
        {
    
            perror("listen");
    
        }
    
        return sock;
    
    }
    
    void* handle(void* argc)
    
    {
    
        int newsock = (int)argc;
    
        char buf[1024];
    
        while(1)
    
        {
    
            int s = read(newsock, buf, sizeof(buf) - 1);
    
            if(s > 0)
    
            {
    
                buf[s] = 0;
    
                printf("client# %s
    ", buf);
    
                write(newsock, buf, strlen(buf));//服务器回显
    
            }
    
            else if(s == 0)
    
            {
    
                printf("client quit
    ");
    
            }
    
            else
    
            {
    
                break;
    
            }
    
        }
    
        close(newsock);
    
    }
    
    //argv[]指针数组,指向各个参数
    
    int main(int argc, char* argv[])
    
    {
    
        if(argc != 3)
    
        {
    
            Usage(argv[0]);
    
            return 2;
    
        }
    
        int listen_sock = startup(argv[1], atoi(argv[2]));
    
        //printf("sock:%d
    ", listen_sock);
    
        //需要让子进程的子进程去提供服务
    
        //父进程继续监听
    
        char buf[1024];
    
        while(1)
    
        {
    
            struct sockaddr_in client;
    
            socklen_t len = sizeof(client);
    
            int newsock = accept(listen_sock, (struct sockaddr*)&client, &len);
    
            if(newsock < 0)
    
            {
    
                perror("accept");
    
                continue;
    
            }
    
            //将网络中的数据转换为主机用户可以看懂的数据
    
            printf("get a new client %s:%d
    ", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    
            //创建一个新的线程去服务
    
            //主线程只负责监听工作
    
            pthread_t tid;
    
            //pthread_create(&tid, NULL, handle, (void*)newsock);
    
            pthread_detach(tid);
    
    
    
    	/*char buffer[BUFFER_SIZE]; 
    
    	bzero(buffer, BUFFER_SIZE); 
    
    	char file_name[FILE_NAME_MAX_SIZE+1];  
    
    	bzero(file_name, FILE_NAME_MAX_SIZE+1);  
    
        	strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));  
    
    	printf("%s
    ", file_name);  
    
        	FILE *fp = fopen(file_name, "w");  
    
        	if(NULL == fp)  
    
        	{  
    
    	    printf("File: %s Can Not Open To Write
    ", file_name);  
    
    	    exit(1);  
    
        	}  
    
       	bzero(buffer, BUFFER_SIZE);  
    
        	int length = 0;  
    
        	while((length = recv(newsock, buffer, BUFFER_SIZE, 0)) > 0)  
    
        	{  
    
    	    if(strcmp(buffer,"OK")==0) 
    
    		break;
    
    	    if(fwrite(buffer, sizeof(char), length, fp) < length)  
    
    	    {  
    
    	  	printf("File: %s Write Failed!
    ", file_name);  
    
    	    	break;  
    
    	    }  
    
                bzero(buffer, BUFFER_SIZE);  
    
    	}  
    
        	printf("Receive File: %s From Client Successful!
    ", file_name);  
    
        	fclose(fp);
    
    
    
    	int words=0;
    
    	char s[100];
    
    	FILE *fp2;
    
    	if((fp2=fopen(file_name,"r"))==NULL)
    
    	{
    
    	    printf("ERROR!
    ");
    
    	    exit(0);
    
    	}
    
    	while(fscanf(fp2,"%s",s)!=EOF)
    
      	words++;
    
    	fclose(fp2);
    
    	printf("%d words.
    ",words);
    
    	char sendbuf[50];
    
    	sprintf(sendbuf,"%d",words);
    
    	send(newsock,sendbuf,50,0);
    
        	close(newsock);*/
    
        }
    
        close(listen_sock);
    
        return 0;
    
    }
    
    
    

    在这里插入图片描述
    分析原因:相较于单线程而言,多线程的各种进程可以同时执行,而不需要像单线程一样排队执行,不易出现进程阻塞,性能更好

    1. 用wc命令检查
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191123141702980.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDgyNjMzOA==,size_16,color_FFFFFF,t_70

    并发程序-3

    实验要求

    • 交叉编译多线程版本服务器并部署到实验箱中

    • PC机作客户端测试wc服务器

    • 提交测试截图

    实验步骤

    1.参照实验一,将PC连接到试验箱,并使其能互相ping通。
    在这里插入图片描述

    1. 在ubuntu上交叉编译
      在这里插入图片描述
  • 相关阅读:
    A debugger is already attached
    鼠标指向GridView某列显示DIV浮动列表
    天气插件的替换
    ZPL打印中文信息
    「PowerBI」使用TabularEditor进行PowerBIDeskTop模型开发最佳实践
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(下)
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(中)
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(上)
    「Azure」数据分析师有理由爱Azure之十-使用PowerShell自动化AzureAS
    「Azure」数据分析师有理由爱Azure之九-填坑-PowerBI Pro连接Azure AS模型
  • 原文地址:https://www.cnblogs.com/thz666/p/11917931.html
Copyright © 2020-2023  润新知