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!\n");
        exit(1);
    }

    fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
    if(fd_temp == -1)
    {
        fprintf(stderr,"listen error!\n");
        exit(1);
    }

    while(1)
    {
        printf("waiting for new connection...\n");
        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!\n");
            continue;                               //ignore current socket ,continue while loop.
        }
        printf("A new connection occurs!\n");
        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\n");
    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!\n";
	char data_send[100];
	strcat(data_send,inet_ntoa(s_addr_client.sin_addr));
//	puts(s_addr_client.sin_addr)
	strcat(data_send,"\n20155308\n");
 while(1)
    {
        printf("waiting for request...\n");
        //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\n");
            break;
        }
        if(i_recvBytes == -1)
        {
            fprintf(stderr,"read error!\n");
            break;
        }
        if(strcmp(data_recv,"quit")==0)
        {
            printf("Quit command!\n");
            break;                           //Break the while loop.
        }
        printf("read from client : %s\n",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...\n");
    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!\n");
        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! \n");
        exit(1);
    }

    while(1)
    {
        printf("Please input something you wanna say(input \"quit\" to quit):\n");
        gets(data_send);
        //scanf("%[^\n]",data_send);         //or you can also use this
        tempfd = write(sockfd,data_send,BUFFER_LENGTH);
        if(tempfd == -1)
        {
            fprintf(stderr,"write error\n");
            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\n",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\t");
    printf("客户端IP:%s\n",inet_ntoa(clie_addr.sin_addr)); 
    
        time_t t = time(0); 
        char tmp[64]; 
        strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A\n\t", 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]='\0';
        printf("当前时间:%s\n",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!\n");
        exit(1);
    }

    fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);

    if(fd_temp == -1)
    {
        fprintf(stderr,"listen error!\n");
        exit(1);
    }

   while(1)
    {
        //printf("waiting for new connection...\n");
        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\n\t", localtime(&t) ); 
    send(sockfd,tmp,strlen(tmp),0); 
    close(sockfd);  //close a file descriptor.
        if(sockfd == -1)
        {
            fprintf(stderr,"Accept error!\n");
            continue;                               //ignore current socket ,continue while loop.
        }

        if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)
        {
            fprintf(stderr,"pthread_create error!\n");
            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\t");
    printf("客户端IP:%s\n",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]='\0';
        printf("当前时间:%s\n",buff);
    } 
}
    //关闭套节字
    close(cfd);
    return 0;
}
  • 代码中出现的问题

  • 问题1

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


这样就可以编译成功了!

  • 问题2

    连接不上?不知道为什么?正在解决中。。。。
posted @ 2017-11-12 20:58  郝文菲20155308  阅读(206)  评论(0编辑  收藏  举报