• 实验四(2)


    服务器端代码:

    #include    <stdio.h>
    #include    <sys/types.h>
    #include    <sys/stat.h>
    #include    <string.h>
    
    int main(int ac, char *av[])
    {
        int     sock, fd;
        FILE    *fpin;
        char    request[BUFSIZ];
    
        if ( ac == 1 ){
            fprintf(stderr,"usage: ws portnum
    ");
            exit(1);
        }
        sock = make_server_socket( atoi(av[1]) );
        if ( sock == -1 ) exit(2);
    
        /* main loop here */
    
        while(1){
            /* take a call and buffer it */
            fd = accept( sock, NULL, NULL );
            fpin = fdopen(fd, "r" );
    
            /* read request */
            fgets(request,BUFSIZ,fpin);
            printf("got a call: request = %s", request);
            read_til_crnl(fpin);
    
            /* do what client asks */
            process_rq(request, fd);
    
            fclose(fpin);
        }
    }
    
    /* ------------------------------------------------------ *
       read_til_crnl(FILE *)
       skip over all request info until a CRNL is seen
       ------------------------------------------------------ */
    
    read_til_crnl(FILE *fp)
    {
        char    buf[BUFSIZ];
        while( fgets(buf,BUFSIZ,fp) != NULL && strcmp(buf,"
    ") != 0 )
            ;
    }
    
    /* ------------------------------------------------------ *
       process_rq( char *rq, int fd )
       do what the request asks for and write reply to fd 
       handles request in a new process
       rq is HTTP command:  GET /foo/bar.html HTTP/1.0
       ------------------------------------------------------ */
    
    process_rq( char *rq, int fd )
    {
        char    cmd[BUFSIZ], arg[BUFSIZ];
    
        /* create a new process and return if not the child */
        if ( fork() != 0 )
            return;
    
        strcpy(arg, "./");        /* precede args with ./ */
        if ( sscanf(rq, "%s%s", cmd, arg+2) != 2 )
            return;
    
        if ( strcmp(cmd,"GET") != 0 )
            cannot_do(fd);
        else if ( not_exist( arg ) )
            do_404(arg, fd );
        else if ( isadir( arg ) )
            do_ls( arg, fd );
        else if ( ends_in_cgi( arg ) )
            do_exec( arg, fd );
        else
            do_cat( arg, fd );
    }
    
    /* ------------------------------------------------------ *
       the reply header thing: all functions need one
       if content_type is NULL then don't send content type
       ------------------------------------------------------ */
    
    header( FILE *fp, char *content_type )
    {
        fprintf(fp, "HTTP/1.0 200 OK
    ");
        if ( content_type )
            fprintf(fp, "Content-type: %s
    ", content_type );
    }
    
    /* ------------------------------------------------------ *
       simple functions first:
            cannot_do(fd)       unimplemented HTTP command
        and do_404(item,fd)     no such object
       ------------------------------------------------------ */
    
    cannot_do(int fd)
    {
        FILE    *fp = fdopen(fd,"w");
    
        fprintf(fp, "HTTP/1.0 501 Not Implemented
    ");
        fprintf(fp, "Content-type: text/plain
    ");
        fprintf(fp, "
    ");
    
        fprintf(fp, "That command is not yet implemented
    ");
        fclose(fp);
    }
    
    do_404(char *item, int fd)
    {
        FILE    *fp = fdopen(fd,"w");
    
        fprintf(fp, "HTTP/1.0 404 Not Found
    ");
        fprintf(fp, "Content-type: text/plain
    ");
        fprintf(fp, "
    ");
    
        fprintf(fp, "The item you requested: %s
    is not found
    ", 
                item);
        fclose(fp);
    }
    
    /* ------------------------------------------------------ *
       the directory listing section
       isadir() uses stat, not_exist() uses stat
       do_ls runs ls. It should not
       ------------------------------------------------------ */
    
    isadir(char *f)
    {
        struct stat info;
        return ( stat(f, &info) != -1 && S_ISDIR(info.st_mode) );
    }
    
    not_exist(char *f)
    {
        struct stat info;
        return( stat(f,&info) == -1 );
    }
    
    do_ls(char *dir, int fd)
    {
        FILE    *fp ;
    
        fp = fdopen(fd,"w");
        header(fp, "text/plain");
        fprintf(fp,"
    ");
        fflush(fp);
    
        dup2(fd,1);
        dup2(fd,2);
        close(fd);
        execlp("ls","ls","-l",dir,NULL);
        perror(dir);
        exit(1);
    }
    
    /* ------------------------------------------------------ *
       the cgi stuff.  function to check extension and
       one to run the program.
       ------------------------------------------------------ */
    
    char * file_type(char *f)
    /* returns 'extension' of file */
    {
        char    *cp;
        if ( (cp = strrchr(f, '.' )) != NULL )
            return cp+1;
        return "";
    }
    
    ends_in_cgi(char *f)
    {
        return ( strcmp( file_type(f), "cgi" ) == 0 );
    }
    
    do_exec( char *prog, int fd )
    {
        FILE    *fp ;
    
        fp = fdopen(fd,"w");
        header(fp, NULL);
        fflush(fp);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
        execl(prog,prog,NULL);
        perror(prog);
    }
    /* ------------------------------------------------------ *
       do_cat(filename,fd)
       sends back contents after a header
       ------------------------------------------------------ */
    
    do_cat(char *f, int fd)
    {
        char    *extension = file_type(f);
        char    *content = "text/plain";
        FILE    *fpsock, *fpfile;
        int    c;
    
        if ( strcmp(extension,"html") == 0 )
            content = "text/html";
        else if ( strcmp(extension, "gif") == 0 )
            content = "image/gif";
        else if ( strcmp(extension, "jpg") == 0 )
            content = "image/jpeg";
        else if ( strcmp(extension, "jpeg") == 0 )
            content = "image/jpeg";
    
        fpsock = fdopen(fd, "w");
        fpfile = fopen( f , "r");
        if ( fpsock != NULL && fpfile != NULL )
        {
            header( fpsock, content );
            fprintf(fpsock, "
    ");
            while( (c = getc(fpfile) ) != EOF )
                putc(c, fpsock);
            fclose(fpfile);
            fclose(fpsock);
        }
        exit(0);
    }

    远程登录华为云,以及运行服务器代码:

     本地wsl中充当客户端:telnet 121.36.82.213 8000

     eg2:

     此时的服务器端显示:

    在本地服务器上登录121.36.82.213:8000可得:(此时本地浏览器充当客户端,在华为云web服务器端上有显示:(eg:got a call: request = GET / HTTP/1.1)

     

     

     

  • 相关阅读:
    实现继承的几种方式
    使用 + 操作符、parseInt 、 parseFloat等方法处理数字字符串时的不同
    jQuery插件版无缝轮播,重写了之前的代码,显得更高大上一点
    我是如何从零开始构建一个jsp项目的
    css居中方法详解
    嫌innerHTML性能不够好,推荐几个新方法
    初学事件委托
    Set集合——HashSet、TreeSet、LinkedHashSet(2015年07月06日)
    十大Intellij IDEA快捷键(转)(2015年06月15日)
    IntelliJ IDEA 集成Tomcat后找不到HttpServlet问题(2015年06月13日)
  • 原文地址:https://www.cnblogs.com/hhxz1234/p/14140767.html
Copyright © 2020-2023  润新知