zoukankan      html  css  js  c++  java
  • 信息安全系统设计基础第五次实验报告

    北京电子科技学院(BESTI)

    实 验 报 告

    课程:信息安全系统设计基础 班级: 1353

    姓名:(按贡献大小排名)朱锂 陈都

    学号:(按贡献大小排名)20135319 20135328

    成绩: 指导教师: 娄嘉鹏 实验日期:11.10

    实验密级: 预习程度: 实验时间:15:30—18:00

    仪器组次: 必修/选修:必修 实验序号:5

    实验名称:信息安全系统设计基础EXP5—简单嵌入式WEB服务器实验

    实验目的与要求:

    1 看懂代码,在宿主机和实验箱中实现。

    2 查找C语言密码算法库,在通信中使用密码算法

    实验内容与步骤:

    1 进入/arm2410cl/exp/basic/07_httpd 目录,使用 vi 编辑器或其他编辑器阅读理解源代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <signal.h>
    #include <unistd.h>
    #include <ctype.h>
    #include "pthread.h"
    
    #define DEBUG
    
    int KEY_QUIT=0;
    int TIMEOUT=30;
    
    #ifndef O_BINARY
    #define O_BINARY 0
    #endif
    
    char referrer[128];
    int content_length;
    
    #define SERVER_PORT 80
    
    int PrintHeader(FILE *f, int content_type)
    //发送http协议数据头
    //参数一表示客户连接的文件流指针
    //参数二表示信息类型
    {
      alarm(TIMEOUT);
      fprintf(f,"HTTP/1.0 200 OK
    ");
      switch (content_type)
      { 
       case 't':
        fprintf(f,"Content-type: text/plain
    ");
        break;
       case 'g':
        fprintf(f,"Content-type: image/gif
    ");
        break;
       case 'j':
        fprintf(f,"Content-type: image/jpeg
    ");
        break;
       case 'h':
        fprintf(f,"Content-type: text/html
    ");
        break;
      }
      fprintf(f,"Server: uClinux-httpd 0.2.2
    ");
      fprintf(f,"Expires: 0
    ");
      fprintf(f,"
    ");
      alarm(0);
      return(0);
    }
    
    int DoJpeg(FILE *f, char *name)
    //发送jpeg
    //参数一文件数据信息
    //参数二文件名
    {
      char *buf;
      FILE * infile;
      int count;
     
      if (!(infile = fopen(name, "r"))) {
        alarm(TIMEOUT);
        fprintf(stderr, "Unable to open JPEG file %s, %d
    ", name, errno);
        fflush(f);
        alarm(0);
        return -1;
      }
     
      PrintHeader(f,'j');	
    
     
      copy(infile,f); /* prints the page */
     
      alarm(TIMEOUT);
      fclose(infile);
      alarm(0);
     
      return 0;
    }
    
    int DoGif(FILE *f, char *name)
    //发送gif文件
    //参数一文件数据信息
    //参数二文件名
    {
      char *buf;
      FILE * infile;
      int count;
    
      if (!(infile = fopen(name, "r"))) {
        alarm(TIMEOUT);
        fprintf(stderr, "Unable to open GIF file %s, %d
    ", name, errno);
        fflush(f);
        alarm(0);
        return -1;
      }
    
      PrintHeader(f,'g');
    
      copy(infile,f); /* prints the page */  
    
      alarm(TIMEOUT);
      fclose(infile);
      alarm(0);
      
      return 0;
    }
    
    int DoDir(FILE *f, char *name)
    //发送当前目录列表信息
    //参数一文件流指针用于写入目录文件信息数据
    //参数二客户请求的目录信息
    {
      char *buf;
      DIR * dir;
      struct dirent * dirent;
    
      if ((dir = opendir(name))== 0) {
        fprintf(stderr, "Unable to open directory %s, %d
    ", name, errno);
        fflush(f);
        return -1;
      }
      
      PrintHeader(f,'h');
      
      alarm(TIMEOUT);
      fprintf(f, "<H1>Index of %s</H1>
    
    ",name);
      alarm(0);
    
      if (name[strlen(name)-1] != '/') {
    	strcat(name, "/");
      }
      
      while(dirent = readdir(dir)) {
    	alarm(TIMEOUT);
      
    	fprintf(f, "<p><a href="/%s%s">%s</a></p>
    ", name, dirent->d_name, dirent->d_name);
    	alarm(0);
      }
      
      closedir(dir);
      return 0;
    }
    
    int DoHTML(FILE *f, char *name)
    //发送 HTML 文件内容
    //参数一写入文件数据信息
    //参数二客户请求的文件名
    {
      char *buf;
      FILE *infile;
      int count;
      char * dir = 0;
    
      if (!(infile = fopen(name,"r"))) {
        alarm(TIMEOUT);
        fprintf(stderr, "Unable to open HTML file %s, %d
    ", name, errno);
        fflush(f);
        alarm(0);
        return -1;
      }
    
      PrintHeader(f,'h');
      copy(infile,f); /* prints the page */  
    
      alarm(TIMEOUT);
      fclose(infile);
      alarm(0);
    
      return 0;
    }
    
    int DoText(FILE *f, char *name)
    //发送纯文本文件内容
    //参数一写入文件信息数据
    //参数二写入文件名
    {
      char *buf;
      FILE *infile;
      int count;
    
      if (!(infile = fopen(name,"r"))) {
        alarm(TIMEOUT);
        fprintf(stderr, "Unable to open text file %s, %d
    ", name, errno);
        fflush(f);
        alarm(0);
        return -1;
      }
    
      PrintHeader(f,'t');
      copy(infile,f); /* prints the page */  
    
      alarm(TIMEOUT);
      fclose(infile);
      alarm(0);
    
      return 0;
    }
    
    int ParseReq(FILE *f, char *r)
    //解析客户请求,参数一表示客户连接的文件流指针
    //参数二,待解析的字符串
    {
      	char *bp;
      	struct stat stbuf;
      	char * arg;
      	char * c;
      	int e;
      	int raw;
    
    #ifdef DEBUG
      	printf("req is '%s'
    ", r);
    #endif
      
      	while(*(++r) != ' ');  /*skip non-white space*/
      	while(isspace(*r))
      		r++;
      
      	while (*r == '/')
      		r++;
      	bp = r;
      
      	while(*r && (*(r) != ' ') && (*(r) != '?'))
      		r++;
      	
    #ifdef DEBUG
      	printf("bp='%s' %x, r='%s' 
    ", bp, *bp,r);
    #endif
      	
      	if (*r == '?')
      	{
      		char * e;
      		*r = 0;
      		arg = r+1;
      		if (e = strchr(arg,' ')) 
    		{
      			*e = '';
      		}
      	} else 
        {
      		arg = 0;
    	  	*r = 0;
        }
      
      	c = bp;
    
      
      	if (c[0] == 0x20){
    		c[0]='.';
    		c[1]=''; 
    	}
    	if(c[0] == '') strcat(c,".");
    		
    	if (c && !stat(c, &stbuf)) 
      	{
        	if (S_ISDIR(stbuf.st_mode)) 
        	{ 
        		char * end = c + strlen(c);
        		strcat(c, "/index.html");
        		if (!stat(c, &stbuf)) 
            	{
        			DoHTML(f, c);
        		} 
            	else 
            	{
      				*end = '';
    				DoDir(f,c);
    			}
        	}
        	else if (!strcmp(r - 4, ".gif"))
          		DoGif(f,c);
            else if (!strcmp(r - 4, ".jpg") || !strcmp(r - 5, ".jpeg"))
              	DoJpeg(f,c);
            else if (!strcmp(r - 4, ".htm") || !strcmp(r - 5, ".html"))
                DoHTML(f,c);
                 else
                      DoText(f,c);
    	} 
    	else{
    	  	PrintHeader(f,'h');
      		alarm(TIMEOUT);
    	  	fprintf(f, "<html><head><title>404 File Not Found</title></head>
    ");
    		fprintf(f, "<body>The requested URL was not found on this server</body></html>
    ");
    	  	alarm(0);
        }
      	return 0;
    }
    
    void sigalrm(int signo)
    {
    	exit(0);
    }
    
    int HandleConnect(int fd)//控制连接
    {
      FILE *f;
    
      char buf[160];
      char buf1[160];
    
      f = fdopen(fd,"a+");
      if (!f) {
        fprintf(stderr, "httpd: Unable to open httpd input fd, error %d
    ", errno);
        alarm(TIMEOUT);
        close(fd);
        alarm(0);
        return 0;
      }
      setbuf(f, 0);
    
      alarm(TIMEOUT);
    
      if (!fgets(buf, 150, f)) {
        fprintf(stderr, "httpd: Error reading connection, error %d
    ", errno);
        fclose(f);
        alarm(0);
        return 0;
      }
    #ifdef DEBUG
      	printf("buf = '%s'
    ", buf);
    #endif
        
      	alarm(0);
    
      	referrer[0] = '';
      	content_length = -1;
        
     	alarm(TIMEOUT);
    
    	while (fgets(buf1, 150, f) && (strlen(buf1) > 2)) {
      		alarm(TIMEOUT);
    		#ifdef DEBUG
    	    	printf("Got buf1 '%s'
    ", buf1);
    		#endif
        	if (!strncasecmp(buf1, "Referer:", 8)) {
    	      	char * c = buf1+8;
        	  	while (isspace(*c))
    				c++;
    		    strcpy(referrer, c);
        	} 
        	else if (!strncasecmp(buf1, "Referrer:", 9)) {
          		char * c = buf1+9;
         		 while (isspace(*c))
    				c++;
          		strcpy(referrer, c);
        	} 
        	else if (!strncasecmp(buf1, "Content-length:", 15)) {
          		content_length = atoi(buf1+15);
        	} 
      	}
      	alarm(0);
      
      	if (ferror(f)) {
        	fprintf(stderr, "http: Error continuing reading connection, error %d
    ", errno);
    	    fclose(f);
        	return 0;
      	}	
        
      	ParseReq(f, buf);
    
      	alarm(TIMEOUT);
      	fflush(f);
      	fclose(f);
      	alarm(0);
      	return 1;
    }
    
    
    
    void* key(void* data)
    {
    	int c;
    	for(;;){
    		c=getchar();	
    		if(c == 'q' || c == 'Q'){
    			KEY_QUIT=1;
    			exit(10);
    			break;
    		}
    	}
    		
    }
    
    int main(int argc, char *argv[])
    {
      int fd, s;
      int len;
      volatile int true = 1;
      struct sockaddr_in ec;
      struct sockaddr_in server_sockaddr;
    	  
      pthread_t th_key;
      void * retval;
    
    
      signal(SIGCHLD, SIG_IGN);
      signal(SIGPIPE, SIG_IGN);
      signal(SIGALRM, sigalrm);
    
      chroot(HTTPD_DOCUMENT_ROOT);
      printf("starting httpd...
    ");
      printf("press q to quit.
    ");
    //  chdir("/");
    
      if (argc > 1 && !strcmp(argv[1], "-i")) {
        /* I'm running from inetd, handle the request on stdin */
        fclose(stderr);
        HandleConnect(0);
        exit(0);
      }
    
      if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
        perror("Unable to obtain network");
        exit(1);
      }
      
      if((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&true, 
    		 sizeof(true))) == -1) {
        perror("setsockopt failed");
        exit(1);
      }
    
      server_sockaddr.sin_family = AF_INET;
      server_sockaddr.sin_port = htons(SERVER_PORT);
      server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
      
      if(bind(s, (struct sockaddr *)&server_sockaddr, 
    	  sizeof(server_sockaddr)) == -1)  {
        perror("Unable to bind socket");
        exit(1);
      }
    
      if(listen(s, 8*3) == -1) { /* Arbitrary, 8 files/page, 3 clients */
        perror("Unable to listen");
        exit(4);
      }
    
      
       	pthread_create(&th_key, NULL, key, 0);
      /* Wait until producer and consumer finish. */
      printf("wait for connection.
    ");	
      while (1) {
    	  
        len = sizeof(ec);
        if((fd = accept(s, (void *)&ec, &len)) == -1) {
          exit(5);
          close(s);
        }
        HandleConnect(fd);
    	
      }
      pthread_join(th_key, &retval);
    }
    

    2 编译应用程序 运行 make 产生可执行文件 httpd

    [root@zxt /]# cd /arm2410cl/exp/basic/07_httpd/
    [root@zxt 07_httpd]# make
    armv4l-unknown-linux-gcc -DHTTPD_DOCUMENT_ROOT="/mnt/yaffs" -c -o httpd.o httpd.c
    armv4l-unknown-linux-gcc -DHTTPD_DOCUMENT_ROOT="/mnt/yaffs" -c -o copy.c
    armv4l-unknown-linux-gcc -o ../bin/httpd httpd.o copy.o -lpthread
    armv4l-unknown-linux-gcc -o httpd httpd.o copy.o -lpthread
    [root@zxt 07_httpd]# ls
    copy.c doc httpd httpd.o Makefile
    copy.o Google httpd.c index.html Makefile.bak
    

    3 下载调试 使用 NFS 服务方式将 HTTPD 下载到开发板上,并拷贝测试用的网

    页进行调试,本例中用的是 index 测试网页。

    [/mnt/yaffs] mount -t nfs -o nolock 192.168.0.56:/arm2410cl /host
    [/mnt/yaffs]cd /host/exp/basic/07_httpd/
    [/host/exp/basic/07_httpd]./httpd
    starting httpd...
    press q to quit.
    wait for connection.
    

    实验体会:

    通过这次实验,我们又知道了一种嵌入式系统的应用方法,由于操作的层面比通常开发web应用所在层次更加底层,这对于我们对于web应用的深入理解也是一种加强。

  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/20135319zl/p/5043483.html
Copyright © 2011-2022 走看看