• 2017-2018-1 20155308 《信息安全系统设计基础》第八周课上+课下测试


    2017-2018-1 20155308 《信息安全系统设计基础》第八周课上+课下测试

    课堂测试

    任务一

    参考 http://www.cnblogs.com/rocedu/p/6766748.html#SECCLA 在Linux下完成“求命令行传入整数参数的和”

    测试代码传入自己的8位学号

    上方提交代码

    附件提交运行测试截图

    • 实验过程
    #include <stdio.h>
    int main( int argc, char *argv[] )
    {
        int i;
        int sum;
        for( i=1;i<argc;i++ )
        {
           sum +=atoi(argv[i]);//atoi()函数把字符串转换成整型数
        }
    
        printf("%d",sum);
        return 0;
    }
    

    • 实验中问题
      这个题是比较简单的,但是我在提交的过程中出现了错误,然后就没有提交上。
      这个代码中有一个注意事项:即调用“atoi()函数把字符串转换成整型数”。如果没有调用这个函数,就会出现这个情况。

      就是因为类型没有转换!

    任务二

    把第一个练习中的代码在X86-64(Ubuntu)中反汇编,给出汇编代码和机器码的截图

    把X86-64汇编翻译成Y86-64汇编,并给出相应机器码的截图(使用附件中的Y86-64模拟器)

    • 实验过程
    1. 首先查看汇编代码

    1. 反编译查看机器代码

    1. Y86-64汇编

    0x0000:                        | Disassembly of section .text:
                                   | 
    0x0000:                        | 00000000 <bubble_p>:
    0x0000:                        |    0:  56                      push   %esi
    0x0000:                        |    1:  53                      push   %ebx
    0x0000:                        |    2:  8b 44 24 10             mov    0x10(%esp),%eax
    0x0000:                        |    6:  8b 54 24 0c             mov    0xc(%esp),%edx
    0x0000:                        |    a:  8d 70 ff                lea    -0x1(%eax),%esi
    0x0000:                        |    d:  85 f6                   test   %esi,%esi
    0x0000:                        |    f:  7e 2d                   jle    3e <bubble_p+0x3e>
    0x0000:                        |   11:  8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi
    0x0000:                        |   18:  31 c0                   xor    %eax,%eax
    0x0000:                        |   1a:  8d b6 00 00 00 00       lea    0x0(%esi),%esi
    0x0000:                        |   20:  8b 4c 82 04             mov    0x4(%edx,%eax,4),%ecx
    0x0000:                        |   24:  8b 1c 82                mov    (%edx,%eax,4),%ebx
    0x0000:                        |   27:  39 d9                   cmp    %ebx,%ecx
    0x0000:                        |   29:  7d 07                   jge    32 <bubble_p+0x32>
    0x0000:                        |   2b:  89 5c 82 04             mov    %ebx,0x4(%edx,%eax,4)
    0x0000:                        |   2f:  89 0c 82                mov    %ecx,(%edx,%eax,4)
    0x0000:                        |   32:  83 c0 01                add    $0x1,%eax
    0x0000:                        |   35:  39 f0                   cmp    %esi,%eax
    0x0000:                        |   37:  7c e7                   jl     20 <bubble_p+0x20>
    0x0000:                        |   39:  83 ee 01                sub    $0x1,%esi
    0x0000:                        |   3c:  75 da                   jne    18 <bubble_p+0x18>
    0x0000:                        |   3e:  5b                      pop    %ebx
    0x0000:                        |   3f:  5e                      pop    %esi
                                   |   
    0x0000:                        | Disassembly of section .text.startup:
                                   | 
    0x0000:                        | 00000000 <main>:
    0x0000:                        |    0:  31 c0                   xor    %eax,%eax
                                   |   
                                   |
    

    任务三:

    基于socket 使用教材的csapp.h csapp.c,实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端
    服务器响应消息格式是

    “
    客户端IP:XXXX
    服务器实现者学号:XXXXXXXX
    当前时间: XX:XX:XX
    ”
    

    上方提交代码

    提交一个客户端至少查询三次时间的截图测试截图

    提交至少两个客户端查询时间的截图测试截图

    • 客户端
    #include "time.h"
    #include<stdlib.h>
    #include<pthread.h>
    #include<sys/socket.h>
    #include<sys/types.h>       //pthread_t , pthread_attr_t and so on.
    #include<stdio.h>
    #include<netinet/in.h>      //structure sockaddr_in
    #include<arpa/inet.h>       //Func : htonl; htons; ntohl; ntohs
    #include<assert.h>          //Func :assert
    #include<string.h>          //Func :memset
    #include<unistd.h>          //Func :close,write,read
    #define SOCK_PORT 13224
    #define BUFFER_LENGTH 1024
    #define MAX_CONN_LIMIT 512     //MAX connection limit
    struct sockaddr_in s_addr_client;
    
    static void Data_handle(void * sock_fd);   //Only can be seen in the file
    
    int main()
    {
        int sockfd_server;
        int sockfd;
        int fd_temp;
        struct sockaddr_in s_addr_in;
       
        int client_length;
    
        sockfd_server = socket(AF_INET,SOCK_STREAM,0);  //ipv4,TCP
        assert(sockfd_server != -1);
    
        //before bind(), set the attr of structure sockaddr.
        memset(&s_addr_in,0,sizeof(s_addr_in));
        s_addr_in.sin_family = AF_INET;
        s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);  //trans addr from uint32_t host byte order to network byte order.
        s_addr_in.sin_port = htons(SOCK_PORT);          //trans port from uint16_t host byte order to network byte order.
        fd_temp = bind(sockfd_server,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));
        if(fd_temp == -1)
        {
            fprintf(stderr,"bind error!
    ");
            exit(1);
        }
    
        fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
        if(fd_temp == -1)
        {
            fprintf(stderr,"listen error!
    ");
            exit(1);
        }
    
        while(1)
        {
            printf("waiting for new connection...
    ");
            pthread_t thread_id;
            client_length = sizeof(s_addr_client);
    
            //Block here. Until server accpets a new connection.
            sockfd = accept(sockfd_server,(struct sockaddr *)(&s_addr_client),(socklen_t *)(&client_length));
            if(sockfd == -1)
            {
                fprintf(stderr,"Accept error!
    ");
                continue;                               //ignore current socket ,continue while loop.
            }
            printf("A new connection occurs!
    ");
            pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd));
        }
    
        //Clear
        int ret = shutdown(sockfd_server,SHUT_WR); //shut down the all or part of a full-duplex connection.
        assert(ret != -1);
    
        printf("Server shuts down
    ");
        return 0;
    }
    
    static void Data_handle(void * sock_fd)
    {
        int fd = *((int *)sock_fd);
        int i_recvBytes;
        char data_recv[BUFFER_LENGTH];
    	char ip[20];
    	
         //char * data_send = "Server has received your request!
    ";
    	char data_send[100];
    	strcat(data_send,inet_ntoa(s_addr_client.sin_addr));
    //	puts(s_addr_client.sin_addr)
    	strcat(data_send,"
    20155308
    ");
     while(1)
        {
            printf("waiting for request...
    ");
            //Reset data.
            memset(data_recv,0,BUFFER_LENGTH);
    
            i_recvBytes = read(fd,data_recv,BUFFER_LENGTH);
            if(i_recvBytes == 0)
            {
                printf("Maybe the client has closed
    ");
                break;
            }
            if(i_recvBytes == -1)
            {
                fprintf(stderr,"read error!
    ");
                break;
            }
            if(strcmp(data_recv,"quit")==0)
            {
                printf("Quit command!
    ");
                break;                           //Break the while loop.
            }
            printf("read from client : %s
    ",data_recv);
            if(write(fd,data_send,strlen(data_send)) == -1)
            {
                break;
            }
    	time_t timep;
       	time (&timep);
       	
    	if(write(fd,ctime(&timep),strlen(ctime(&timep))) == -1)
            {
                break;
            }
    	
        }
    
        //Clear
        printf("terminating current client_connection...
    ");
        close(fd);            //close a file descriptor.
        pthread_exit(NULL);   //terminate calling thread!
    }
    
    • 客户端
    #include<stdlib.h>
    #include<sys/socket.h>
    #include<sys/types.h>       //pthread_t , pthread_attr_t and so on.
    #include<stdio.h>
    #include<netinet/in.h>      //structure sockaddr_in
    #include<arpa/inet.h>       //Func : htonl; htons; ntohl; ntohs
    #include<assert.h>          //Func :assert
    #include<string.h>          //Func :memset
    #include<unistd.h>          //Func :close,write,read
    #define SOCK_PORT 13224
    #define BUFFER_LENGTH 1024
    int main()
    {
        int sockfd;
        int tempfd;
        struct sockaddr_in s_addr_in;
        char data_send[BUFFER_LENGTH];
        char data_recv[BUFFER_LENGTH];
        memset(data_send,0,BUFFER_LENGTH);
        memset(data_recv,0,BUFFER_LENGTH);
    
        sockfd = socket(AF_INET,SOCK_STREAM,0);       //ipv4,TCP
        if(sockfd == -1)
        {
            fprintf(stderr,"socket error!
    ");
            exit(1);
        }
    
        //before func connect, set the attr of structure sockaddr.
        memset(&s_addr_in,0,sizeof(s_addr_in));
        s_addr_in.sin_addr.s_addr = inet_addr("127.0.0.1");      //trans char * to in_addr_t
        s_addr_in.sin_family = AF_INET;
        s_addr_in.sin_port = htons(SOCK_PORT);
    
        tempfd = connect(sockfd,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));
        if(tempfd == -1)
        {
            fprintf(stderr,"Connect error! 
    ");
            exit(1);
        }
    
        while(1)
        {
            printf("Please input something you wanna say(input "quit" to quit):
    ");
            gets(data_send);
            //scanf("%[^
    ]",data_send);         //or you can also use this
            tempfd = write(sockfd,data_send,BUFFER_LENGTH);
            if(tempfd == -1)
            {
                fprintf(stderr,"write error
    ");
                exit(0);
            }
    
            if(strcmp(data_send,"quit") == 0)  //quit,write the quit request and shutdown client
            {
                break;
            }
            else
            {
                tempfd = read(sockfd,data_recv,BUFFER_LENGTH);
                assert(tempfd != -1);
                printf("%s
    ",data_recv);
                memset(data_send,0,BUFFER_LENGTH);
                memset(data_recv,0,BUFFER_LENGTH);
            }
        }
    
        int ret = shutdown(sockfd,SHUT_WR);       //or you can use func close()--<unistd.h> to close the fd
        assert(ret != -1);
        return 0;
    }
    
    • 运行结果:

    课下作业

    课下作业1

    1. 完成家庭作业4.47,4.48,4.49
    2. 相应代码反汇编成X86-64汇编
    3. 把上述X86-64汇编翻译成Y86汇编,并给出相应机器码

    发操作过程、测试、问题解决过程博客链接

    1. 4.47
    void bubble(int *data,int c)
    {
       int i,j;
       int *p,*q;
       for(i=c-1;i!=0;i--){
           p=data;
           q=data+1;
           for(j=0;j!=i;++j)
            {
                if(*p>*q)
                {
                    int t=*p;
                    *p=*q;
                    *q=t;
                 }
             p++;
             q++;
        }
    }
    }
    

    y86

    movl $8, %ecx  
    pushl %ecx  #count = 8 
    movl data, %ecx
    pushl %ecx #push data call bubble halt  
    bubble:
    pushl %ebp movl %esp, %ebp 
    pushl %esi 
    pushl %ebx 
    pushl %edx 
    movl 8(%ebp), %edx   #edx == data movl 12(%ebp), %esi  #esi == count andl %esi, %esi 
    je 
    bubbleEnd #count==0 movl $1, %eax 
    subl %eax, %esi #count-- je bubbleEnd #count==1  
    OuterLoop: 
    movl %edx, %ecx # p = data (ecx) pushl %esi# to save one reg  
    InnerLoop: 
    movl (%ecx), %eax 
    movl 4(%ecx), %ebx
    subl %eax, %ebx
    movl 4(%ecx), %ebx jg NoSwap 
    movl %eax, %ebx #swap, so ebx is greater movl 4(%ecx), %eax  
    NoSwap: 
    movl %eax, (%ecx)
    movl %ebx, 4(%ecx) movl $4, %eaxaddl %eax, %ecx
    movl $1, %eax
    subl%eax, %esi jne
    InnerLoop  
    popl %esi
    movl $1, %eax
    subl %eax, %esi jne
    OuterLoop  
    bubbleEnd:
    popl %edx
    popl %ebx
    popl %esi
    movl %ebp, %esp
    popl %ebp
    ret
    

    这个代码我运行后,出现了这个问题?

    这个问题不知道怎么解决?

    课下作业2

    • 把课上练习3的daytime服务器分别用多进程和多线程实现成并发服务器并测试
    • 实验过程
    1. 多进程:

    多进程实现daytime服务器,因此需要用到fork()函数创建进程,而课堂上所实现的daytime服务器每次只是接收一个客户端的请求,这会导致服务器的效率比较低下。因此可以采用多进程并发技术提高服务器的处理效率。

    • 服务端
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<string.h>
    #include<ctype.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<errno.h>
    #include<errno.h>
    #include <time.h>
    
    #define SERV_PORT 13321
    
    int std_err(const char* name)
    {
        perror(name);
        exit(1);
    }
    
    int main(void)
    {
        int sfd, cfd, ret;
        int len;
        pid_t pid;
        socklen_t clie_len;
    
        char buf[BUFSIZ], clibuf[32];
    
        //创建服务器套节字
        sfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sfd == -1)
            std_err("socket");
    
        //定义地址类型
        struct sockaddr_in serv_addr, clie_addr;
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERV_PORT);
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        //绑定服务器的IP、端口;
        ret = bind(sfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
        if(ret == -1)
            std_err("bind");
    
        //监听链接服务器的客户数量
        ret = listen(sfd, 3);
        if(ret == -1)
            std_err("listen");
        clie_len = sizeof(clie_addr);
    
        while(1)
        {
            //阻塞等待客户端发起链接请求
            cfd = accept(sfd, (struct sockaddr*)&clie_addr, &clie_len);
        printf("服务器实现者20155308	");
        printf("客户端IP:%s
    ",inet_ntoa(clie_addr.sin_addr)); 
        
            time_t t = time(0); 
            char tmp[64]; 
            strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A
    	", localtime(&t) ); 
    
        //这里无需打印当前时间,应该是客户端打印当前时间
    
            if(cfd == -1)
                std_err("accept");
    
            pid = fork();
    
            if(pid < 0)
                std_err("fork:");
    
            else if(pid == 0)
            {
                close(sfd);
                break;
            }
            else        //住进程实现逻辑;1.回收子进程,2,关闭不必要的文件描述父 3,继续等待客户端链接,如果有,则继续创建子进程
            {
                send(cfd,tmp,strlen(tmp),0);
                close(cfd);
            }
        }
        return 0;
    }
    
    • 客户端
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<string.h>
    #include<strings.h>
    #include<ctype.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<signal.h>
    #include<errno.h>
    #include<pthread.h>
    #include <pthread.h>
    
    #define SERV_PORT 13321
    #define SERV_IP "127.0.0.1"
    #define NUM 3
    
    int std_err(const char* name)
    {
        perror(name);
        exit(1);
    }
    
    int main(void)
    {
        int cfd, ret;
        char buf[BUFSIZ];
        pid_t pid;
    
        int i;
        for(i = 0; i < NUM; i++){
            pid = fork();
            if(pid == 0)
                break;
            else if(pid < 0)
                std_err("fork");
        }
    
       
        if(pid == 0)
        {
            cfd = socket(AF_INET, SOCK_STREAM, 0);
            if(cfd == -1)
                std_err("socket");
    
            struct sockaddr_in clie_addr;
            clie_addr.sin_family = AF_INET;
            clie_addr.sin_port = htons(SERV_PORT);
            ret = inet_pton(AF_INET, SERV_IP, &clie_addr.sin_addr.s_addr);
            if(ret != 1)
                std_err("inet_pton");
    
           ret = connect(cfd, (struct sockaddr*)&clie_addr, sizeof(clie_addr));
            if(ret == -1)
                std_err("connect");
    
        char buff[256];
        int nRecv=recv(cfd,buff,256,0);
        if(nRecv>0)
        {   
            buff[nRecv]='';
            printf("当前时间:%s
    ",buff);
        } 
        }
        close(cfd);
        return 0;
    
    }
    
    
    • 运行结果
    1. 多线程:

    创建一个新的进程本身开销还是比较大的,因为这样会消耗很多务器端的资源。因此可以采用多线程的方法来实现服务器端。

    • 服务端
    #include<stdio.h>
    #include<stdlib.h>
    #include<pthread.h>
    #include<sys/socket.h>
    #include<sys/types.h>     
    #include<netinet/in.h>     
    #include<arpa/inet.h>       
    #include<assert.h>         
    #include<string.h>        
    #include<unistd.h>           :close,write,read
    #include<ctype.h>
    #include<arpa/inet.h>
    #include <time.h>
    #define SOCK_PORT 9988
    #define BUFFER_LENGTH 1024
    #define MAX_CONN_LIMIT 5   
    
    static void Data_handle(void * sock_fd);
    struct sockaddr_in s_addr_in;
    struct sockaddr_in s_addr_client;
    int sockfd;
    
    int main()
    {
        int sockfd_server
        int fd_temp;
        int client_length;
    
        sockfd_server = socket(AF_INET,SOCK_STREAM,0);  //ipv4,TCP
        assert(sockfd_server != -1);
    
        //before bind(), set the attr of structure sockaddr.
        memset(&s_addr_in,0,sizeof(s_addr_in));
        s_addr_in.sin_family = AF_INET;
        s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);  //trans addr from uint32_t host byte order to network byte order.
        s_addr_in.sin_port = htons(SOCK_PORT);          //trans port from uint16_t host byte order to network byte order.
    
        fd_temp = bind(sockfd_server,(struct scokaddr*)(&s_addr_in),sizeof(s_addr_in));
    
        if(fd_temp == -1)
        {
            fprintf(stderr,"bind error!
    ");
            exit(1);
        }
    
        fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
    
        if(fd_temp == -1)
        {
            fprintf(stderr,"listen error!
    ");
            exit(1);
        }
    
       while(1)
        {
            //printf("waiting for new connection...
    ");
            pthread_t thread_id;
            client_length = sizeof(s_addr_client);
    
            //Block here. Until server accpets a new connection.
            sockfd = accept(sockfd_server,(struct sockaddr*)(&s_addr_client),&client_length);
    
        time_t t = time(0); 
            char tmp[64]; 
            strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A
    	", localtime(&t) ); 
        send(sockfd,tmp,strlen(tmp),0); 
        close(sockfd);  //close a file descriptor.
            if(sockfd == -1)
            {
                fprintf(stderr,"Accept error!
    ");
                continue;                               //ignore current socket ,continue while loop.
            }
    
            if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)
            {
                fprintf(stderr,"pthread_create error!
    ");
                break;                                  //break while loop
            }
        }
    
        //Clear
        int ret = shutdown(sockfd_server,SHUT_WR); //shut down the all or part of a full-duplex connection.
        assert(ret != -1);
    
        return 0;
    }
    
    static void Data_handle(void * sock_fd)
    {
        int fd = *((int *)sock_fd);
        int i_recvBytes;
        char data_recv[BUFFER_LENGTH];
       
        printf("服务器实现者20155308	");
        printf("客户端IP:%s
    ",inet_ntoa(s_addr_client.sin_addr)); 
        pthread_exit(NULL);   //terminate calling thread!
    }
    
    
    • 服务器
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<string.h>
    #include<ctype.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<signal.h>
    #include<errno.h>
    #include<pthread.h>
    #include <pthread.h>
    #define SERV_PORT 13321
    #define SERV_IP "127.0.0.1"
    #define NUM 3
    int std_err(const char* name)
    {
        perror(name);
        exit(1);
    }
    
    int main(void)
    {
        int cfd, ret;
        char buf[BUFSIZ];
        pid_t pid;
    
        int i;
    
        //创建套节字
        cfd = socket(AF_INET, SOCK_STREAM, 0);
        if(cfd == -1)
            std_err("socket");
    
        //定义IP , 端口
        struct sockaddr_in clie_addr;
        clie_addr.sin_family = AF_INET;
        clie_addr.sin_port = htons(SERV_PORT);
    
        //转换IP 字符串的地址
        ret = inet_pton(AF_INET, SERV_IP, &clie_addr.sin_addr.s_addr);
        if(ret != 1)
            std_err("inet_pton");
    
        //链接服务器
        ret = connect(cfd, (struct sockaddr*)&clie_addr, sizeof(clie_addr));
        if(ret == -1)
            std_err("connect");
            char buff[256];
        int nRecv=recv(cfd,buff,256,0);
        if(nRecv>0)
        {   
            buff[nRecv]='';
            printf("当前时间:%s
    ",buff);
        } 
    }
        //关闭套节字
        close(cfd);
        return 0;
    }
    
    • 代码中出现的问题

    • 问题1

    解决过程:记得要加上-lpthread参数,这样编译就可以顺利通过了。lpthread是表示要连接到pthread的库是这里省略的lib,你应该可以找到共享库libpthread.so的。


    这样就可以编译成功了!

    • 问题2

      连接不上?不知道为什么?正在解决中。。。。
  • 相关阅读:
    狄慧201771010104《面向对象程序设计(java)》第十六周学习总结
    狄慧201771010104《面向对象程序设计(java)》第十五周学习总结
    狄慧201771010104《面向对象程序设计(java)》第十四周学习总结
    201771030122-王瑞梅 实验二 个人项目—《西北师范大学学生疫情上报系统》项目报告
    201771030122-王瑞梅 实验一 软件工程准备—<初读《构建之法--现代软件工程》>
    软件工程学习总结
    团队项目在GitHub合作开发管理流程
    2020 软件工程—— 中期获“衣”有感
    201771010131-王之泰 实验四 软件项目案例分析
    数据库连接和导出excal
  • 原文地址:https://www.cnblogs.com/JIUSHA/p/7822877.html
Copyright © 2020-2023  润新知