• 2017-2018-1 20155306 实验三 实时系统


    2017-2018-1 20155306 实验三 实时系统

    实验内容:

    任务一

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

    通过man命令得知:

    • 命令格式
      wc [选项]文件...
    • 命令功能
      统计指定文件中的字节数、字数、行数,并将统计结果显示输出。该命令统计指定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所指定文件的总统计数。
    • 命令参数
      -c 统计字节数。
      -l 统计行数。
      -m 统计字符数。这个标志不能与 -c 标志一起使用。
      -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。
      -L 打印最长行的长度。
      -help 显示帮助信息
      --version 显示版本信息
      SERVER :
    #include <sys/time.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define PORT 155306
    
    #define BACKLOG 1
    #define MAXRECVLEN 1024
    
    int main(int argc, char *argv[])
    {
        char buf[MAXRECVLEN];
        int listenfd, connectfd;  /* socket descriptors */
        struct sockaddr_in server; /* server's address information */
        struct sockaddr_in client; /* client's address information */
        socklen_t addrlen;
        /* Create TCP socket */
        if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            /* handle exception */
            perror("socket() error. Failed to initiate a socket");
            exit(1);
        }
     
        /* set socket option */
        int opt = SO_REUSEADDR;
        setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
        bzero(&server, sizeof(server));
    
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
        {
            /* handle exception */
            perror("Bind() error.");
            exit(1);
        }
        
        if(listen(listenfd, BACKLOG) == -1)
        {
            perror("listen() error. 
    ");
            exit(1);
        }
    
        addrlen = sizeof(client);
        while(1){
            if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)
              {
                perror("accept() error. 
    ");
                exit(1);
              }
            FILE *stream;
            struct timeval tv;
            gettimeofday(&tv, NULL);
              printf(" Client ip :  %s 
    ",inet_ntoa(client.sin_addr));
    	  printf(" Port id : %d 
     ",htons(client.sin_port));
    	  printf("Time is %ld.%ld
    ",tv.tv_sec,tv.tv_usec);
            
            int iret=-1;
            char d[1024];
             iret = recv(connectfd, buf, MAXRECVLEN, 0);
                if(iret>0)
                {
                   strcpy(d,buf);
                    stream = fopen(buf,"r");
                    bzero(buf, sizeof(buf));
                    //strcat(buf,"Word number:");
    strcat(buf,"Word number:");
                    char s[21];
    long int count = 0;
                    while(fscanf(stream,"%s",s)!=EOF)
                    count++;
                    char str[10];
    sprintf(str, " %ld
    ", count); 
    int n = sizeof(str);
    str[n] = ''; 
    strcat(buf,"
    ");
    
    //strcat(buf,"	");strcat(buf,str);
    printf("
    ");
    
    strcat(buf,"
    ");
                    
                }else
                {
                    close(connectfd);
                    break;
                }
                /* print client's ip and port */
                send(connectfd, buf, iret, 0); /* send to the client welcome message */
            }
        
        close(listenfd); /* close listenfd */
        return 0;
    }
    

    CLIENT:

    
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>  /* netdb is necessary for struct hostent */
    
    #define PORT 155306  /* server port */
    
    #define MAXDATASIZE 100
    
    int main(int argc, char *argv[])
    {
        int sockfd, num;    /* files descriptors */
        char buf[MAXDATASIZE];    /* buf will store received text */
        struct hostent *he;    /* structure that will get information about remote host */
        struct sockaddr_in server;
        
        if (argc != 3)
        {
            printf("Usage: %s <IP Address><Filename>
    ",argv[0]);
            exit(1);
        }
        
        if((he=gethostbyname(argv[1]))==NULL)
        {
            printf("gethostbyname() error
    ");
            exit(1);
        }
        
        if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1)
        {
            printf("socket() error
    ");
            exit(1);
        }
        bzero(&server,sizeof(server));
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);
        server.sin_addr = *((struct in_addr *)he->h_addr);
        if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)
        {
            printf("connect() error
    ");
            exit(1);
        }
    char str[MAXDATASIZE] ;
    strcpy(str,argv[2]);
    
    if((num=send(sockfd,str,sizeof(str),0))==-1){
          printf("send() error
    ");
            exit(1);
        }
        if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
        {
            printf("recv() error
    ");
            exit(1);
        }
        buf[num-1]='';
        printf(" Successful! 
     %s
    ",buf);
    
        close(sockfd);
        return 0;
    }
    
    

    运行截图如下:

    任务二

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

    进程同步

    进程同步也是进程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。

    比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。而当进程A产生信息放入缓冲区时,进程B才会被唤醒。概念如图1所示。

    进程互斥

    进程互斥是进程之间的间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

    比如进程B需要访问打印机,但此时进程A占有了打印机,进程B会被阻塞,直到进程A释放了打印机资源,进程B才可以继续执行。概念如图2所示。

    运行截图如下:

  • 相关阅读:
    第三章 套接字编程简介
    Effective STL 学习关于容器
    C++单例模板
    第六章 IO复用:select和poll函数
    第五章 TCP客户服务器程序示例
    八、基本UDP套接字编程
    第四章 基本TCP套接字编程
    测试 LaTeX
    如何在不支持 LaTeX 的环境使用 LaTeX 命令输入公式?
    Ubuntu 下 Wine 安装微软 Office
  • 原文地址:https://www.cnblogs.com/0831j/p/7862806.html
Copyright © 2020-2023  润新知