zoukankan      html  css  js  c++  java
  • 实验三-并发程序 20175201张驰

    实验三-实时系统-1
    任务详情

    学习使用Linux命令wc(1)
    基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端
    客户端传一个文本文件给服务器
    服务器返加文本文件中的单词数
    上方提交代码
    附件提交测试截图,至少要测试附件中的两个文件
    查看wc的功能

    在终端中输入man wc查看wc的功能

    代码

    服务器端server

    //
    //  main.c
    //  server
    //
    //  Created by shadow on 2019/11/17.
    //  Copyright © 2019 shadow. All rights reserved.
    //
    
    #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
    
    #define SERVER_PORT 175201
    #define LENGTH_OF_LISTEN_QUEUE 20
    #define BUFFER_SIZE 1024
    #define FILE_NAME_MAX_SIZE 512
    
    int main(void)
    {
        // 声明并初始化一个服务器端的socket地址结构
        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);
        
        // 创建socket,若成功,返回socket描述符
        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));
        
        // 绑定socket和socket地址结构
        if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))
        {
            perror("Server Bind Failed:");
            exit(1);
        }
        
        // socket监听
        if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))
        {
            perror("Server Listen Failed:");
            exit(1);
        }
        
        while(1)
        {
            // 定义客户端的socket地址结构
            struct sockaddr_in client_addr;
            socklen_t client_addr_length = sizeof(client_addr);
            
            // 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信
            // accept函数会把连接到的客户端信息写到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;
            }
            
            // recv函数接收数据到缓冲区buffer中
            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;
            }
            
            // 然后从buffer(缓冲区)拷贝到file_name中
            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);
            }
            
            // 从客户端接收数据到buffer中
            // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止
            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);
            }
            
            
            // 接收成功后,关闭文件,关闭socket
            printf("Receive %s successful!
    ", file_name);
            fclose(fp);
            
            
            // 统计文件单词个数,并发送给客户端
            int words=0;
            char s[1000];
            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);
            
            
            sprintf(buffer,"%d",words);
            
            send(new_server_socket_fd,buffer,BUFFER_SIZE,0);
            
            //send(new_server_socket_fd,&words,sizeof(words),0);
            close(new_server_socket_fd);
            
            
            
            // 关闭与客户端的连接
            
        }
        // 关闭监听用的socket
        close(server_socket_fd);
        return 0;
    } 
    

    客户端client

    //
    //  main.c
    //  client
    //
    //  Created by shadow on 2019/11/17.
    //  Copyright © 2019 shadow. All rights reserved.
    //
    
    #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
    
    #define SERVER_PORT 175201
    #define BUFFER_SIZE 1024
    #define FILE_NAME_MAX_SIZE 512
    
    int main()
    {
        // 声明并初始化一个客户端的socket地址结构
        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);
        
        // 创建socket,若成功,返回socket描述符
        int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(client_socket_fd < 0)
        {
            perror("Create Socket Failed:");
            exit(1);
        }
        
        // 绑定客户端的socket和客户端的socket地址结构 非必需
        if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
        {
            perror("Client Bind Failed:");
            exit(1);
        }
        
        // 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接
        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);
        
        // 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接
        if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
        {
            perror("Can Not Connect To Server IP:");
            exit(0);
        }
        
        // 输入文件名,并放到缓冲区buffer中等待发送
        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));
        
        // 向服务器发送buffer中的数据
        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);
            }
            
            // 关闭文件
            
            fclose(fp);
            printf("Transfer file %s successful!
    ", file_name);
            send(client_socket_fd,"OK",BUFFER_SIZE,0);
            recv(client_socket_fd,buffer,BUFFER_SIZE,0);
            printf("%d
    ",atoi(buffer));
        }
        
        close(client_socket_fd);
        return 0;
    }
    

    代码运行结果



    实验三-实时系统-2
    任务详情

    使用多线程实现wc服务器并使用同步互斥机制保证计数正确
    上方提交代码
    下方提交测试
    对比单线程版本的性能,并分析原因!
    实验操作步骤

    服务器端

    #include<netinet/in.h>   
    #include<sys/types.h>   
    #include<sys/socket.h>   
    #include<stdio.h>   
    #include<stdlib.h>   
    #include<string.h>   
    #include<pthread.h>  
    #define HELLO_WORLD_SERVER_PORT    175201  
    #define LENGTH_OF_LISTEN_QUEUE     20  
    #define BUFFER_SIZE                1024  
    #define FILE_NAME_MAX_SIZE         512  
    void *process_client(void *new_server_socket);
    int mywc(char file_name[])
    {
        char ch;
        int flag=0,num=0;
        int choose;
        FILE *fp;
        printf("统计单词个数还是实现“wc -w”?(1or2)
    ");
        scanf("%d",&choose);
        if((fp = fopen(file_name,"r"))==NULL)
        {
            printf("Failure to open %s
    ",file_name);
            exit(0);
        }
    
        if(choose==1)
        {
        while((ch=fgetc(fp))!=EOF)
        {
            if(ch==' ' || ch=='
    ' || ch=='	' ||  ch=='!' || ch=='?' || ch=='"' || ch=='.' || ch== '\,' || ch==':' || ch=='(' || ch==')' || ch==';' || ch=='-')
            {
                flag=0;
            }
            else
            {
                if(flag==0)
                {
                    flag=1;
                    num++;
                }
    
            }
                       
        }
    
        }
        else if(choose==2)
        {
            while((ch=fgetc(fp))!=EOF)
            {
                if(ch==' ' || ch=='
    ' || ch=='	' || ch=='
    ')
                    flag=0;
                else
                {
                    if(flag==0)
                    {
                        flag=1;
                        num++;
                    }
                }
            }
        }
        printf("单词个数为:%d
    ",num);
        fclose(fp);
        return num;
    }
    int main(int argc, char **argv)  
    {  
    // set socket's address information   
    // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口  
        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(HELLO_WORLD_SERVER_PORT);  
    // create a stream socket   
    // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口  
        int server_socket = socket(PF_INET, SOCK_STREAM, 0);  
        if (server_socket < 0)  
        {  
            printf("Create Socket Failed!
    ");  
            exit(1);  
        }  
    
    // 把socket和socket地址结构绑定   
        if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))  
        {  
            printf("Server Bind Port: %d Failed!
    ", HELLO_WORLD_SERVER_PORT);  
            exit(1);  
        }  
    
    // server_socket用于监听   
        if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))  
        {  
            printf("Server Listen Failed!
    ");  
            exit(1);  
        }  
    // 服务器端一直运行用以持续为客户端提供服务   
          
        while(1)
        {
    // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept  
    // 接受此请求,同时将client端的地址和端口等信息写入client_addr中  
            struct sockaddr_in client_addr;  
            socklen_t length = sizeof(client_addr);  
    
    
            int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);  
            printf("连接到客户端
    ");
            if (new_server_socket < 0)  
            {  
                printf("Server Accept Failed!
    ");  
                  
            }
            //添加进程相关代码
            pthread_t pid;
            if(pthread_create(&pid, NULL, process_client,(void *) &new_server_socket) < 0){
                  printf("pthread_create error
    ");
            }
            
        }
    //  close(server_socket);
    }
    void *process_client(void *new_server_socket)
    {
            int sockid=*(int *)new_server_socket;
            FILE *fp;
            //接受来自客户端的文件
            char buffer[BUFFER_SIZE]; 
            char file_name[FILE_NAME_MAX_SIZE];
            bzero(buffer, sizeof(buffer));  
            int length=0;
            if(recv(sockid,buffer,BUFFER_SIZE, 0)==-1)
            {
                printf("接受文件名%s失败
    ",buffer);
            }
            strcpy(file_name,buffer);
            strcat(file_name,"-server");
            if((fp = fopen(file_name,"w"))==NULL)
            {
                printf("Failure to open %s
    ",file_name);
                exit(0);
            }
            while( length = recv(sockid, buffer, BUFFER_SIZE, 0))
            {
                if(length<0)
                {
                    printf("接受文件出错
    ");
                    exit(0);
                }
                
                if(fwrite(buffer,sizeof(char),length,fp)<length)
                {
                    printf("写文件失败
    ");
                }
                bzero(buffer, BUFFER_SIZE);
            }
            fclose(fp);
            printf("接受文件完毕
    ");
            int number=0;
            number=mywc(file_name);
            bzero(buffer, BUFFER_SIZE);  
            buffer[0]=number+48;
     
         
            bzero(buffer, sizeof(buffer));  
            
    
            printf("File Transfer Finished!
    ");    
            close(new_server_socket);  
    } 
    

    客户端

    #include<netinet/in.h>                         // for sockaddr_in  
    #include<sys/types.h>                          // for socket  
    #include<sys/socket.h>                         // for socket  
    #include<stdio.h>                              // for printf  
    #include<stdlib.h>                             // for exit  
    #include<string.h>                             // for bzero  
      
    #define HELLO_WORLD_SERVER_PORT       175201  
    #define BUFFER_SIZE                   1024  
    #define FILE_NAME_MAX_SIZE            512  
    int mywc(char file_name[],int choose);
    int main(int argc, char **argv)  
    {  
        FILE *fp;
        if (argc != 2)  
        {  
            printf("Usage: ./%s ServerIPAddress
    ", argv[0]);  
            exit(1);  
        }  
    
    // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口  
        struct sockaddr_in client_addr;  
        bzero(&client_addr, sizeof(client_addr));  
        client_addr.sin_family = AF_INET; // internet协议族  
        client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址  
        client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口  
    
    // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket  
        int client_socket = socket(AF_INET, SOCK_STREAM, 0);  
        if (client_socket < 0)  
        {  
            printf("Create Socket Failed!
    ");  
            exit(1);  
        }  
    
    // 把客户端的socket和客户端的socket地址结构绑定   
        if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))  
        {  
            printf("Client Bind Port Failed!
    ");  
            exit(1);  
        }  
    
    // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口  
        struct sockaddr_in  server_addr;  
        bzero(&server_addr, sizeof(server_addr));  
        server_addr.sin_family = AF_INET;  
    
    // 服务器的IP地址来自程序的参数   
        if (inet_aton(argv[1], &server_addr.sin_addr) == 0)  
        {  
            printf("Server IP Address Error!
    ");  
            exit(1);  
        }                                                                                                               
        server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);  
        socklen_t server_addr_length = sizeof(server_addr);  
        // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接  
        if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)  
        {  
            printf("Can Not Connect To %s!
    ", argv[1]);  
            exit(1);  
        }  
    
        char file_name[FILE_NAME_MAX_SIZE + 1];  
        bzero(file_name, sizeof(file_name));  
        printf("Please Input File Name.	");  
        scanf("%s", file_name);  
        if((fp = fopen(file_name,"r"))==NULL)
        {
             printf("Failure to open %s
    ",file_name);
             exit(0);
        }
        
        char buffer[BUFFER_SIZE];  
        bzero(buffer, sizeof(buffer));  
        strcpy(buffer,file_name);
        if(send(client_socket,buffer,BUFFER_SIZE,0)==-1)
        {
            printf("发送文件名失败
    ");
        }
        char ch;
        int i=0;
        while((ch=fgetc(fp))!=EOF)
        {
            buffer[i++]=ch;
            if(i>=BUFFER_SIZE)
            {
                if((send(client_socket, buffer, BUFFER_SIZE, 0))==-1)
                {
                    printf("发送文件失败
    ");
                }
                bzero(buffer, sizeof(buffer));
                i=0;
            }
        }
        if(i<BUFFER_SIZE)
        {
            if((send(client_socket, buffer, i, 0))==-1)
            {
                printf("发送文件失败
    ");
            }
        }
        printf("发送%s完毕
    ",file_name);
        mywc(file_name,1);
         mywc(file_name,2);
        // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件 
        //以下接收服务器发来的单词个数
        bzero(buffer, sizeof(buffer));
    
        fclose(fp);  
        close(client_socket);  
        return 0;  
    
    }  
     int mywc(char file_name[],int choose)
      {
           FILE *fp;
           char ch;
            int flag=0,num=0;
           
                if((fp = fopen(file_name,"r"))==NULL)
                 {
                      printf("Failure to open %s
    ",file_name);
                       exit(0);
                    }
                 
                      if(choose==1)
                       {
                        while((ch=fgetc(fp))!=EOF)
                         {
                              if(ch==' ' || ch=='
    ' || ch=='	' ||  ch=='!' || ch=='?' || ch=='"' || ch=='.' || ch== '\,' || ch==':' || ch=='(' || ch==')' || ch==';'     || ch=='-')
                              {
                              flag=0;
                              }
                              else
                              {
                              if(flag==0)
                              {
                              flag=1;
                              num++;
                              }
                              
                              }
    
                        }
    
                    }
                    else if(choose==2)
                    {
                        while((ch=fgetc(fp))!=EOF)
                        {
                            if(ch==' ' || ch=='
    ' || ch=='	' || ch=='
    ')
                            flag=0;
                            else
                            {
                                if(flag==0)
                                {
                                    flag=1;
                                    num++;
                                }
                            }
                        }
                    }
                    printf("单词个数为:%d_用方式%d计算
    ",num,choose);
                    fclose(fp);
                    return num;
    }
    

    实验截图

  • 相关阅读:
    Palindrome Partitioning
    Minimum Path Sum
    Maximum Depth of Binary Tree
    Minimum Depth of Binary Tree
    Unique Binary Search Trees II
    Unique Binary Search Trees
    Merge Intervals
    Merge Sorted Array
    Unique Paths II
    C++ Primer Plus 笔记第九章
  • 原文地址:https://www.cnblogs.com/20175201zc/p/11876389.html
Copyright © 2011-2022 走看看