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&&字符为‘ ’、'\n'、'\r'、'\t'的一种)
        计数一次;
    if(字符为' '、'\n'、'\r'、'\t'的一种) 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\n", 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\n", 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]=='\n' || buffer[i]=='\r')){
                                wordscount++;
                    }
                    if(buffer[i]== ' ' || buffer[i]=='\n' || buffer[i]=='\r') 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]=='\n' || buffer[i]=='\r')){
                                wordscount++;
                    }
                }
                if(buffer[i]== ' ' || buffer[i]=='\n' || buffer[i]=='\r') 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\n", inet_ntoa(remote_addr.sin_addr));
        pthread_create(&t, NULL, &my_wc, NULL);
        pthread_join(&t, NULL);
    }
    close(serverfd);
}

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

3、截图

posted @ 2018-11-18 11:05  Maxeys  阅读(225)  评论(0编辑  收藏  举报