zoukankan      html  css  js  c++  java
  • Web服务器2socket实现web服务器

    Web服务器-socket编程

    20191331 lyx

    实验内容

    基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用Linux Socket实现:

    1. Web服务器的客户端服务器,提交程序运行截图
    2. 实现GET即可,请求,响应要符合HTTP协议规范
    3. 服务器部署到华为云服务器,浏览器用本机的
    4. 把服务器部署到试验箱。(加分项)

    实践开始

    1.代码

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    int KEY_QUIT = 0;
    char referrer[128]={0};
    int content_length=0;
    #define SERVER_PORT 7777
    static char copybuf[16384]={0};
    #define DEBUG 1
    
    int copy(FILE *read_f, FILE * write_f) //复制文本的API函数copy
    {
        int n;
        int wrote;
        n = fread(copybuf,1,sizeof(copybuf),read_f);
        wrote = fwrite(copybuf,n,1,write_f);
        return 0;
    }
    
    int DoHTML(FILE *f, char * name,int fd)
    {
        FILE *infile;
        char buf[1024];
        infile = fopen(name,"r"); //打开本地Client端请求的html文件,文件名为name
    
        printf("Sending headers \n");
        strcpy(buf, "HTTP/1.0 200 OK\r\n");
        send(fd, buf, strlen(buf), 0);
        strcpy(buf, "Server: simple httpd/0.1.0\r\n");
        send(fd, buf, strlen(buf), 0);
        sprintf(buf, "Content-Type: text/html\r\n");
        send(fd, buf, strlen(buf), 0);
        strcpy(buf, "\r\n");
        send(fd, buf, strlen(buf), 0);
        printf("Sending mesg...\n");
        copy(infile,f); //复制Client客户端请求的html文件
        printf("Complete sending.\n");
        fread(copybuf,1,sizeof(copybuf),f);
        fclose(infile);
        return 0;
    }
    
    int ParseReq(FILE *f, char *r,int fd) //分析处理请求文件流当中的内容提取请求的文件名index.html
    {
        char *bp;
        char *c;
        #ifdef DEBUG
        printf("req is %s", r); //请求的内容例如: GET /index.html HTTP/1.1
        #endif
        while(*(++r) != ' '); //去掉请求内容开头所有的空格部分
        while(isspace(*r)) r++; //判断输入字符是否为空格/回车/制表符等,去掉所有的这些字符
        while(*r == '/') r++; //去掉所有的'/'字符
        bp = r; //得到文件名的起始指针
        while(*r && (*r != ' ') && (*r != '?')) r++;
        *r = 0;
        c = bp;
        printf("The Request FileName is %s\n", c);
        DoHTML(f, c ,fd); //得到文件名之后处理请求的操作
        return 0;
    }
    
    int HandleConnect(int fd)
    {
        FILE *f;
        char buf[160];
        f = fdopen(fd, "a+"); //打开对应文件名的html文件
        setbuf(f, 0); //清楚f文件缓存区
        fgets(buf, 150, f); //从Client端请求中获取前面150个字符
        #ifdef DEBUG
        printf("buf is %s", buf);
        #endif
        ParseReq(f, buf , fd); //分析请求的内容
        fflush(f); //清空文件缓冲区,将其内容写入文件
        fclose(f);
        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,sockfd;
        int len;
        volatile int true = 1;
        struct sockaddr_in ec;
        struct sockaddr_in server_sockaddr;
        pthread_t th_key;
        printf("Starting httpd...\n");
        printf("press q to quit..\n");
    
        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,(void*)&true,sizeof(true));
        server_sockaddr.sin_family = AF_INET;
        server_sockaddr.sin_port = htons(SERVER_PORT);
        server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr));
        listen(sockfd,8*3);
    
        pthread_create(&th_key,NULL,key,0);
    
        printf("Wait for connection....\n");
        while(1)
        {
        len = sizeof(ec);
            if((fd=accept(sockfd,(void *)&ec,&len)) == -1)
            {
            exit(0);
            close(sockfd);
            }
        printf("Handle Connection...\n");
            HandleConnect(fd);
        }
    }
    
    

    代码已托管:https://gitee.com/DKY2019/xxaqxt/blob/master/web-socket编程实践/webserver/webserver.c

    2.部署至华为云并运行

    部署编译完成 开始运行

    3.本机浏览器访问(兼容性)

    使用ie浏览器访问

    使用edge浏览器访问

    4.符合http协议规范

    请求报文处理

    响应处理

    参考资料

    C语言实现简单Web服务器 https://www.jianshu.com/p/592b631e1ff1

    github参考项目 https://github.com/EZLippi/Tinyhttpd/blob/master/httpd.c

  • 相关阅读:
    spring缓存笔记 半注解版
    乐优商城项目视频及源码
    spring cloud Eureka
    idea+maven搭建ssh,支持事务,无hibernate文件整合
    BUU->CRYPTO 知识点分类
    file-upl0ad
    [RoarCTF 2019]Simple Upload
    BUU UPLOAD COURSE 1
    [GXYCTF2019]Ping Ping Ping
    [SWPU2019]Web1
  • 原文地址:https://www.cnblogs.com/DKYcaiji/p/15595134.html
Copyright © 2011-2022 走看看