天天看點

20145337 《資訊安全系統設計基礎》實驗五 網絡通信20145337 《資訊安全系統設計基礎》實驗五 網絡通信

20145337 《資訊安全系統設計基礎》實驗五 網絡通信

20145337 《資訊安全系統設計基礎》實驗五 網絡通信

北京電子科技學院(BESTI)

實 驗 報 告

課程:資訊安全系統設計基礎 班級: 1453

姓名:馬月 吉東雲

學号:20135319 20135328

成績: 指導教師: 婁嘉鵬 實驗日期:11.24

實驗密級: 預習程度: 實驗時間:10:00—12:00

儀器組次: 必修/選修:必修 實驗序号:5

實驗名稱:網絡通信

實驗目的與要求:

  1. 掌握在ARM開發闆實作一個簡單的WEB伺服器的過程。
  2. 學習在ARM開發闆上的SOCKET網絡程式設計。
  3. 學習Linux下的signal()函數的使用。

實驗儀器:

  • ARM機 1台
  • PC機 1台
  • REDHAT 1台

    一、實驗内容

  1. 閱讀了解源碼

    進入07_httpd所在的目錄,使用vi編輯器了解源代碼。

  2. 編譯應用程式

    使用gcc編譯器,分别對檔案夾下的copy.c和httpd.c進行編譯,出現copy和httpd的可執行檔案。

    20145337 《資訊安全系統設計基礎》實驗五 網絡通信20145337 《資訊安全系統設計基礎》實驗五 網絡通信
    20145337 《資訊安全系統設計基礎》實驗五 網絡通信20145337 《資訊安全系統設計基礎》實驗五 網絡通信
  3. 下載下傳調試

    使用NFS服務方式将HPPTD下載下傳到開發闆上,并拷貝測試用的網頁進行調試

  4. 本機測試

    在桌上型電腦的浏覽器中輸入http://192.168.0.121,觀察在客戶機的浏覽器中的連結請求結果和在開發闆伺服器上的列印資訊。

    20145337 《資訊安全系統設計基礎》實驗五 網絡通信20145337 《資訊安全系統設計基礎》實驗五 網絡通信

二、代碼了解

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\n");
    switch (content_type)
    { 
    case 't':
    fprintf(f,"Content-type: text/plain\n");
    break;
    case 'g':
    fprintf(f,"Content-type: image/gif\n");
    break;
    case 'j':
    fprintf(f,"Content-type: image/jpeg\n");
    break;
    case 'h':
    fprintf(f,"Content-type: text/html\n");
    break;
    }
    fprintf(f,"Server: uClinux-httpd 0.2.2\n");
    fprintf(f,"Expires: 0\n");
    fprintf(f,"\n");
    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\n", 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\n", 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\n", name, errno);
    fflush(f);
    return -1;
    }
  
    PrintHeader(f,'h');
  
    alarm(TIMEOUT);
    fprintf(f, "<H1>Index of %s</H1>\n\n",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>\n", 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\n", 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\n", 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'\n", 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' \n", bp, *bp,r);
    endif
    
    if (*r == '?')
    {
        char * e;
        *r = 0;
        arg = r+1;
        if (e = strchr(arg,' ')) 
        {
            *e = '\0';
        }
    } else 
    {
        arg = 0;
        *r = 0;
    }
  
    c = bp;

  
    if (c[0] == 0x20){
        c[0]='.';
        c[1]='\0'; 
    }
    if(c[0] == '\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 = '\0';
                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>\n");
        fprintf(f, "<body>The requested URL was not found on this server</body></html>\n");
        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\n", 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\n", errno);
    fclose(f);
    alarm(0);
    return 0;
    }
    ifdef DEBUG
    printf("buf = '%s'\n", buf);
    endif
    
    alarm(0);

    referrer[0] = '\0';
    content_length = -1;
    
    alarm(TIMEOUT);

    while (fgets(buf1, 150, f) && (strlen(buf1) > 2)) {
        alarm(TIMEOUT);
        #ifdef DEBUG
            printf("Got buf1 '%s'\n", 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\n", 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...\n");
      printf("press q to quit.\n");
        //  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.\n"); 
      while (1) {
      
        len = sizeof(ec);
        if((fd = accept(s, (void *)&ec, &len)) == -1) {
          exit(5);
          close(s);
        }
        HandleConnect(fd);
    
      }
      pthread_join(th_key, &retval);
    }
           

三、遇到的問題及解決過程

  • 在實驗中修改了makefile,但還是不能make
  • 解決方案:和其他同學進行比對,再次修改makefile,成功make,得到copy及httpd

posted on 2016-12-04 21:07 20145337馬月 閱讀( ...) 評論( ...) 編輯 收藏

轉載于:https://www.cnblogs.com/5337my/p/6131879.html