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


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

    任务一

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

    蓝墨云班课链接:包含所需要的两个txt文件

    2、实验步骤

    使用man命令学习查看wc指令,结果如下:

    通过man命令我们很快知道接下来的实验中需要用到的便是-w参数——统计字数,仔细查看发现这里他们将字定义为由空白、跳格或换行字符分隔的字符串;

    因此,判断字的逻辑可以这样写:

    for(i=0; i<len; i++){
        if(flag==0&&字符为‘ ’、'
    '、'
    '、'	'的一种)
            计数一次;
        if(字符为' '、'
    '、'
    '、'	'的一种) flag=1;
        else flag=0;
    }
    

    接着编程实现如下:

    ///////////////////
    //client.c
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    #define MYPORT 165325
    
    void main(){
    int clientfd;
    struct sockaddr_in remote_addr;
    char buffer[1024];
    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);
    }
    
    ///////////////////
    //server.c
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    #define MYPORT 165325
    
    void main(){
        int serverfd, clientfd;
        struct sockaddr_in my_addr;
        struct sockaddr_in remote_addr;
    
        char buffer[1024];
        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)&&(buffer[i]== ' ' || buffer[i]=='
    ' || buffer[i]=='
    ')){
                                    wordscount++;
                        }
                        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);
    }
    
    3、运行结果

    任务二

    1、实验要求

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

    上方提交代码

    下方提交测试

    对比单线程版本的性能,并分析原因

    2、代码
    ////////////////////////////
    //server1
    #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 165325
    pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
    int serverfd, clientfd;
    char buffer[1024];
    void *my_wc(){
        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)&&(buffer[i]== ' ' || buffer[i]=='
    ' || buffer[i]=='
    ')){
                                    wordscount++;
                        }
                    }
                    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;
    }
    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, &my_wc, NULL);
            pthread_join(&t, NULL);
        }
        close(serverfd);
    }
    

    只修改服务器端代码即可,编译时使用-lpthread,否则报错:“对‘pthread_create’未定义的引用”等;

    3、截图

  • 相关阅读:
    php RSA加密传输代码示例
    数据库执行语句时,严重注意类型转换的问题
    数据库sql的in操作,解决in的过多
    php利用自定义key,对数据加解密的方法
    修改目录下所有文件的某段内容
    ajax返回json时,js获取类型,是字符串类型
    浅析单点登录,以及不同二级域名下的SSO实现
    samba服务,连接远程开发机
    『转』统计一个日志文件里,单词出现频率的shell脚本
    python的装饰器
  • 原文地址:https://www.cnblogs.com/maxeysblog/p/9977009.html
Copyright © 2020-2023  润新知