zoukankan      html  css  js  c++  java
  • 2017-2018-11 20155307刘浩 20155338常胜杰 20155335俞昆 实验三 实时系统实验报告

    2017-2018-11 20155307刘浩 20155338常胜杰 20155335俞昆 实验三 实时系统

    实验目的

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

    实验步骤
    1.实现wc功能
    2.实现客户端给服务器传文件功能
    3.在客户端调用wc函数统计传过来的文件的单词个数

    要实现客户端和服务器的通信,这些我们在计算机网络中学过,具体为:客户端:socket()→bind()→connect()→send()→recv()→close(),然后服务器:socket()→bind()→accept()→recv()→send()→close()
    为了正确实现统计单词个数的功能,找到其与wc命令的关系,先用「man 1 wc」查看wc命令的manpages,如下所示:

    可见,wc命令的功能是统计指定文件中的字节数、字数、行数,
    发现他的参数等信息如下:

    实验代码如下:点击链接即可

    或者这个是客户端,

    #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>  
    #define PORT 155307 
    
    #define MAXDATASIZE 100
    
    int main(int argc, char *argv[])
    {
        int sockfd, num;    
        char buf[MAXDATASIZE];   
        struct hostent *he;    
        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("server message: %s
    ",buf);
    
        close(sockfd);
        return 0;
    }
    

    这个是服务器:

    #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 155307
    
    #define BACKLOG 1
    #define MAXRECVLEN 1024
    
    int main(int argc, char *argv[])
    {
        char buf[MAXRECVLEN];
        int listenfd, connectfd;  
        struct sockaddr_in server; 
        struct sockaddr_in client; 
        socklen_t addrlen;
    
        if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
    
            perror("socket() error. Failed to initiate a socket");
            exit(1);
        }
     
    
        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)
        {
    
            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("You got a connection from client's ip %s, port %d at time %ld.%ld
    ",inet_ntoa(client.sin_addr),htons(client.sin_port), 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,"单词数:");
                    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,str);
    strcat(buf,"(");
    strcat(buf,d);
    strcat(buf,"单词数)");strcat(buf,"
    ");
                    
                }else
                {
                    close(connectfd);
                    break;
                }
    
                send(connectfd, buf, iret, 0); 
            }
        
        close(listenfd);
        return 0;
    }
    

    最后的结果:

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

    代码如下:

    #include<stdlib.h> 
    int main(int argc, char *argv[]) 
    { 
    char ch; 
    FILE *fp; 
    long count=0; 
    char s[21]; 
    if(argc !=2) 
    { 
    printf("文件名为:%s
    ",argv[0]); 
    exit(EXIT_FAILURE); 
    } 
    exit(EXIT_FAILURE); 
    } 
    while(fscanf(fp,"%s",s)!=EOF) 
    count++; 
    fclose(fp); 
    printf("File %s has %ld characters
    ",argv[1],count); 
    return 0; 
    }
    

    或者可以去这里看一下

    实验结果:

    实验感想:此次实验在Linux下实现了wc命令统计文本文件中的单词数,在任务二中创建了一个并发服务器,节省了时间。可以使服务器同时为多个客户端服务了。

    实验一完成的过程中还不是很困难,只是实验二中要注意下windows的socket转入linux时需要做的一系列改变。

  • 相关阅读:
    配置ASP.NET 2.0环境
    httpwatch
    自定义分页控件
    clear在CSS中的妙用
    Maximum length exceeded错误
    SQLServer数据表分区优化数据库
    游标的使用
    在Sql Server 使用系统存储过程sp_rename修改表名或列名
    SQL Server中如何备份到异机
    SQL Server 中 自定义函数 和 游标 应用的经典案例
  • 原文地址:https://www.cnblogs.com/zhuanyedajiesanshinian/p/7857416.html
Copyright © 2011-2022 走看看